声明一个大数组时,可能会导致堆栈溢出。其中涉及到堆和栈的概念。

3
我试图声明一个1024 x 1024的浮点数数组,但是窗口弹出一条消息:project_name.exe已停止工作...并提供了调试或关闭程序的选项。之前,我成功地声明了1000 x 2的整数数组。我在互联网上搜索了可能的原因,它们说这是内存相关问题,确切地说是“堆栈溢出”。他们说对于浮点数情况更糟糕。
我只需要到小数点后5或6位。
有什么建议或建议吗?我在Python和Matlab中没有遇到这个问题。我正在使用Microsoft Visual Studio 2010。

1
如果你不能坐在代码面前,拥有整个工作环境来排除故障,那么我们如何在没有任何工具和可见性的情况下解决它呢?这确实是一个与内存相关的问题;你需要进行一些调试并找出原因。 - Robert Harvey
如果你的二维数组不需要连续,可以尝试进行1024个单独的1024大小的浮点数组分配。 - Thomas Eding
2个回答

13

你是在一个函数或方法中声明这个变量吗?如果是,那么它是一个经典的堆栈溢出。对于VS2010,请参见http://msdn.microsoft.com/en-us/library/8cxs58a6%28v=vs.100%29.aspx

保留值指定了虚拟内存中的总堆栈分配。对于x86和x64机器,默认的堆栈大小为1 MB。在Itanium芯片组上,默认大小为4 MB。

因此,假设每个float占用4个字节(即浮点数),那么一个1024x1024的浮点数数组需要的空间将达到惊人的4mb,您已经超过了默认的堆栈限制。

请注意,即使您有一个Itanium,也无法完全使用那4mb - 堆栈还需要存储参数,详情请参见http://www.csee.umbc.edu/~chang/cs313.s02/stack.shtml

现在,您可以增加堆栈大小,但某一天您可能需要使用更大的数组,所以这是一场没有赢面的消耗战。最好的解决方案是让这个问题消失,换句话说,不要像下面这样声明变量:

float stuff[1024 * 1024];
你将其声明为:

float *stuff = new float[1024 * 1024];
// do something interesting and useful with stuff
delete[] stuff;

现在,这将被分配到堆上,而不是栈上。请注意,这不是 Robert Harvey 在他的答案中提到的那个堆;你在这里没有/HEAP选项的限制。


3
或者只需使用一个向量,它将为您完成所有这些操作,vector<vector<float>> 将在堆上分配其数据,并通过 RAII 自动释放。 - daniel gratzer
然而,需要注意的是,对于C程序也适用(除了使用malloc/free代替new/delete),因此不使用向量可以使答案更普遍适用。 - mh01

2
你是不是将它声明在栈上了?那么大的对象必须放在堆上!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接