我需要创建一个非常大的数组。我们说50兆字节。
我可以安全地将其创建为普通的静态数组吗?编译器会将它放在堆栈上(可能导致堆栈溢出),还是它足够智能将它放在堆上?
如果没有办法这样做,有什么方法可以在程序启动时使用malloc或“new”进行,但在程序结束时自动释放它?
答案 0 :(得分:3)
据我了解,静态变量并不存在于堆栈中。如果他们这样做了,当他们弹出他们居住的堆栈框架时他们会去哪里?静态函数变量需要在调用之间保持状态,因此逻辑上,静态数据应该保存在堆上。
此外,当程序结束时,所有将自动解除分配。
答案 1 :(得分:2)
这样做的简单方法是使用std :: vector
std::vector data;
data.reserve(<Number of Elements);
或潜在的std :: deque(取决于您的用法)。
编译器会将它放在堆栈上(可能导致堆栈溢出),还是它足够智能将它放在堆上?
堆栈溢出是理论堆栈和理论堆碰撞和混合的时候。如果堆栈将过度使用,那么堆也将失败。
某些系统具有最大堆栈大小(这是编译器和平台特定的),请参阅编译器文档以获取详细信息。因此,通常最好动态分配大型结构(尽管不是直接)。
std :: vector这样做(可能)。它有一个小的本地对象存在但主要的有效负载(通常)是作为动态堆分配实现的。
答案 2 :(得分:2)
根据我的经验,最好在堆上分配如此大的数组(因此通过new) - 在堆栈上分配2 MB后,我在unix系统上看到了程序核心转储... 如果要自动删除,可以使用智能指针(例如,boost :: scoped_array)。但是,既然你提到“当程序结束时自动删除它”,你实际上不需要做任何事情 - 操作系统将在它终止时回收你所有进程的内存。
无论如何,你真的应该使用std :: vector而不是原始数组。
答案 3 :(得分:1)
如果您静态分配它,它将被静态分配。在典型的情况下,可执行文件中会有一些类型的记录,指定特定变量应该是大小为N的零初始化块。加载器通常会尊重它,就像它为程序的代码分配空间一样这样(例如,它会分配地址空间但通常不实际内存来支持它,直到/除非你实际读/写那个内存)。
答案 4 :(得分:0)
按今天的标准,50兆字节并不算太多。
您可以使用C ++ new运算符在程序开头分配它,并在结束时(或在定义的程序段的开头/结尾)使用delete []取消分配它。
如果这个数组代表某个要加载的文件,那么当文件加载到内存中时,最好分配它。最理想的是,您只能将文件的一部分映射到内存中(例如:1MB,2MB或您要使用的其他逻辑“单元”)(请参阅Windows中的MapViewOfFile和UNIX系统中的mmap)。这样,您可以加载非常大的文件而不会耗尽虚拟内存。