使用c数组时堆栈溢出

时间:2018-05-28 22:19:50

标签: c memory

当我定义

void tfooo(){
int arr[SOME_LARGE_NUMBER];
// some code here
}

我正在获得堆栈溢出,但是当我添加静态关键字

void tfooo(){
static int arr[SOME_LARGE_NUMBER];
// some code here
}

一切都很好。

有什么区别?是不是静态数组而不是总是在堆栈上定义的动态数组?

2 个答案:

答案 0 :(得分:2)

通常情况下,声明为自动的对象在堆栈上分配(相对较小),而声明为AddImageDialog的对象在其他地方分配。

请注意,这取决于您的计算机和编译器。

答案 1 :(得分:1)

我正在为静态版本和非静态版本生成汇编代码,唯一的区别是在静态版本中变量不存在。我认为它已被删除,因为它没有用于我的测试。

你在使用变量进入测试吗?也许优化器已将变量移除到静态版本中。

我正在使用gcc。要构建汇编代码,请传递-S参数:

gcc -S main.c

这是用于非静态版本的测试代码:

#define SOME_LARGE_NUMBER (100000000000000000)

int arr[SOME_LARGE_NUMBER];

int main(const int argc, const char* argv[]) {
    return 0;
}

这是静态版本:

#define SOME_LARGE_NUMBER (100000000000000000)

static int arr[SOME_LARGE_NUMBER];

int main(const int argc, const char* argv[]) {
    return 0;
}

这是我得到的差异:

$ diff main.static.s main.nostatic.s 
23a24
>   .comm   _arr,400000000000000000,4 ## @arr

您提供的信息是我能得到的。您可以粘贴有关代码的更多详细信息吗?

编辑:在附加的图像中,我们可以看到Windows应用程序的内存布局。当我们将static修饰符用于函数时,它被存储到.data段而不是程序的堆栈中,因为你没有得到堆栈溢出。在编译时,数组的大小是已知的,因此二进制图像存储了足够的数据空间。两个版本中EXE文件的大小是多少?如果我没有错误,静态版本的EXE文件大小将比无静态版本大得多。我想在加载二进制文件时,数组的大小会保留在数据段中。但是,在使用无静态版本时,它取决于堆栈设置了多少内存。从命令行编译时,可以使用标志“/ F”修改此大小(请参阅此链接https://msdn.microsoft.com/en-us/library/tdkhxaks.aspx)。我没有带有Windows的虚拟机来仔细检查。

enter image description here

概括地说,您的静态变量不会存储到堆栈中,因为在使用静态版本时不会出现堆栈溢出。