当我定义
时void tfooo(){
int arr[SOME_LARGE_NUMBER];
// some code here
}
我正在获得堆栈溢出,但是当我添加静态关键字
时void tfooo(){
static int arr[SOME_LARGE_NUMBER];
// some code here
}
一切都很好。
有什么区别?是不是静态数组而不是总是在堆栈上定义的动态数组?
答案 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的虚拟机来仔细检查。
概括地说,您的静态变量不会存储到堆栈中,因为在使用静态版本时不会出现堆栈溢出。