【发布时间】:2016-12-18 23:40:44
【问题描述】:
我有一些 C 代码。 它的作用很简单,从io中获取一些数组,然后排序。
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_MAX 2000000
int main(void) {
int my_array[ARRAY_MAX];
int w[ARRAY_MAX];
int count = 0;
while (count < ARRAY_MAX && 1 == scanf("%d", &my_array[count])) {
count++;
}
merge_sort(my_array, w, count);
return EXIT_SUCCESS;
}
而且效果很好,但是如果我真的给它一组数字,即 2000000,它会导致堆栈溢出。是的,它用完了所有的堆栈。一种解决方案是使用 malloc() 为这两个变量分配内存空间,将它们移动到堆中,这样完全没有问题。
另一种解决方案是将下面的 2 声明移动到全局范围,使其成为全局变量。
int my_array[ARRAY_MAX];
int w[ARRAY_MAX];
我的导师告诉我,这个解决方案做同样的工作:将这 2 个变量移到堆中。
但是我在网上查了一些文件。全局变量,不用初始化,就驻留在bss段吧?
我在网上查了一下,这个部分的大小只有几个字节。 如何防止堆栈溢出?
或者,因为这两种类型是数组,所以它们是指针,而全局指针驻留在数据段中,表示数据段的大小也可以动态改变?
【问题讨论】:
-
简短回答:您的操作系统和编译器很智能。如果你声明了一个大的全局变量但没有给它赋值(在函数之外),那么存储在可执行文件中的唯一的东西就是变量的大小和位置。加载可执行文件后,操作系统将“分配”足够的内存来保存整个变量(在您访问变量之前,它实际上可能不会分配 RAM)。
-
你可能应该看看Why is the bss segment required?我不确定这是否是重复的,但它们非常密切相关。
-
@EthanReesor 谢谢,但是一旦我加载可执行文件,它会存储在哪里?作为您的上下文,在堆中?
-
AFAIK 它是特定于操作系统的,但通常 BSS 将放置在与代码相邻的进程(虚拟)内存空间的读写部分中; 绝对不是堆。 BSS 部分和数据部分之间的差异即使在运行时不存在,也可以忽略不计。真正的区别在于这两个部分在可执行文件中的编码方式。数据部分存储可执行文件中变量的值,而 BSS 部分仅存储大小和位置。有兴趣的话,明天(太平洋标准时间)我会就进程内存做一个详细的解答,包括虚拟内存的概述。
-
@EthanReesor 谢谢!感谢您的澄清!现在我想我现在得到了答案 :) 但如果你能提供更多细节,那就太好了