2

我需要创建一个非常大的数组。让我们说 50 兆字节。

我可以安全地将它创建为普通的静态数组吗?编译器会将其放入堆栈(可能会导致堆栈溢出),还是会足够聪明地将其放入堆中?

如果没有办法这样做,是否有一种简单的方法可以在程序启动时使用 malloc 或“new”,但在程序结束时自动释放它?

4

5 回答 5

3

据我了解,静态变量并不存在于堆栈中。如果他们这样做了,当你弹出他们所在的堆栈帧时,他们会去哪里?静态函数变量需要在调用之间保持其状态,因此从逻辑上讲,静态数据应该保存在堆上。

此外,当程序结束时,一切都会自动释放。

于 2011-01-31T23:00:13.093 回答
2

最简单的方法是使用 std::vector

std::vector   data;
data.reserve(<Number of Elements);

或潜在的 std::deque (取决于您的使用情况)。

编译器会将其放入堆栈(可能会导致堆栈溢出),还是会足够聪明地将其放入堆中?

堆栈溢出是指理论堆栈和理论堆发生冲突和混合。如果堆栈将溢出,那么堆也将失败。

一些系统有最大大小的堆栈帧(这是编译器和平台特定的)请参阅您的编译器文档以获取详细信息。因此,动态分配巨大的结构通常会更好(尽管不是直接分配)。

std::vector 这样做(可能)。它有一个小的本地对象存在,但主要有效负载(通常)是作为动态堆分配实现的。

于 2011-01-31T22:58:38.437 回答
2

根据我的经验,在堆上分配这么大的数组(因此通过 new )更好 - 我在堆栈上分配 2 MB 后看到了 unix 系统上的程序核心转储......如果你想自动删除,你可以使用智能指针(例如 boost::scoped_array)。但是,由于您提到“程序结束时自动删除它”,您实际上不必做任何事情 - 操作系统将在它终止时回收您的所有进程的内存。

无论如何,你真的应该使用 std::vector 而不是原始数组。

于 2011-01-31T23:14:17.123 回答
1

如果您静态分配它,它将被静态分配。在典型情况下,可执行文件中会有某种记录,指定特定变量应该是大小为 N 的零初始化块。加载程序通常会尊重这一点,就像它为程序代码分配空间一样这样(例如,它会分配地址空间,但通常不会分配实际内存来支持它,直到/除非您实际读/写该内存)。

于 2011-01-31T23:08:01.433 回答
0

按照今天的标准,50 兆字节并不算多。

您可以使用 C++ new 运算符在程序开始时分配它,并在结束时(或在已定义程序部分的开始/结束处)使用 delete[] 解除分配。

如果这个数组代表例如某个要加载的文件,当然最好在文件加载到内存时分配它。最佳情况下,您只能将文件的一部分映射到内存中(例如:1MB、2MB 或您想要使用的其他逻辑“单元”)(请参阅 Windows 中的 MapViewOfFile 和 UNIX 系统中的 mmap)。这样您就可以加载非常大的文件而不会耗尽您的虚拟内存。

于 2011-01-31T23:02:35.613 回答