C++动态内存分配限制

4
在C++中使用new或malloc进行动态分配是否存在任何限制(包括系统限制)? 该系统是64位的,我想分配一个包含约800万个结构体的数组。
编辑:我之前为什么没有自己测试它,是因为我目前没有足够内存的机器,所以我觉得在我的当前机器上测试没有意义。
经过我的测试,我可以成功地分配800万个元素,但是一旦达到约850万个,malloc会返回NULL。每个结构体包含7个浮点数,因此总大小约为22GB。 这个看似随意的限制背后的原因是什么?这台机器有4GB的RAM和4GB虚拟内存,所以我不确定我甚至能够分配那么多。

5
你尝试过吗?尝试起来不应该超过几分钟时间…… - Benjamin Cox
你正在构建的程序也应该是x64的。 - Mohammad
4
对于任何特定的系统,显然会存在一些限制 -- 但这通常会取决于系统配置,例如物理内存量、虚拟内存文件/分区的大小等。 - Jerry Coffin
如果物理内存的容量超过malloc请求的大小,那么malloc返回null的其他原因是什么? - ayu
可能是在C++中是否存在最大数组长度限制?的重复问题。 - phuclv
3个回答

3
限制大约是你的可用RAM加上允许交换到磁盘的空间。记录一下,800百万字节= 800 Mb,所以对于小结构体来说,您可能会在安全侧,甚至可能不需要交换(并且应该避免)。只需尝试并查看它何时崩溃;-)
64位:2 ^ 64/2 ^ 30 = 约17 * 10⁹ GB(对于字节寻址架构,1Gb = 2^30 Bit),因此无需担心。
32位:2 ^ 32 = 约4 GB,因此即使在这里,您也可以保持安全。
有符号值除以2,即使在64位系统上仍然有很多空间。

@Martin:我自己修好了,还有qehgt的评论,可能覆盖了你的编辑。抱歉:( - Mooing Duck
2
此外,千字节不是10^3,而是2^10。32位地址空间的一半已经为操作系统保留。这意味着在32位进程中,您只能分配800万个2字节值。空间并不算太多。 - Puppy
@DeadMg:修正了数字。 - Martin
我该如何固定malloc分配的内存? - huseyin tugrul buyukisik

3

除了运行代码,没有其他方法告诉你这个问题的答案。

"位数"只是指定你要针对的操作系统和架构,我还想强调一点,支持C++程序的每个操作系统都有自己的标准C++库实现(如果你正在使用std库),作为编码人员,你只是使用属于std库的头文件和命名空间,并依赖于通常随操作系统提供的C/C++库来实际运行你的代码。

我还建议依靠测试部分并将内存使用保持在最小限度,一些操作系统还具有一些反溢出技术或类似技术,因此一些操作系统可能会将您的大量分配视为对系统稳定性的威胁,RAM的重度使用也涉及内存控制器的重要角色,就像在X86架构中一样,通常你尝试做的事情不是好事,最终会以一个非常特定的机器和操作系统作为你尝试创建的应用程序的首选目标而告终。

最后,你正在尝试编写C代码而不是C++代码!

malloc()是来自C世界的函数,它还涉及直接内存管理,如直接分配和释放,你的硬件也必须执行大量的间接操作,我是说,非常多,与 ~800百万个结构体。

我建议切换到一个真正的C++结构,如std vector(性能比list更好),或者切换到一种具有自己的垃圾回收器且没有直接内存管理阶段的语言,如C#或Java。

你的问题的答案是否定的,从实用角度来看,你将面临一个关于优化代码的大问题,可能,我说可能,使用不同的语言如C++、C#或Java会让你的生活更轻松,但请记住,垃圾回收器通常需要大量内存,对于你的情况,最好的解决方案可能是在你进行额外的努力和测试阶段后选择C++。


我并不是故意要使用malloc,只是想知道malloc和new之间是否有任何不同的限制。此外,malloc会告诉我分配失败的情况。 - ayu

0

对于动态分配,与静态分配相同的限制适用。例如,您只受可用内存量的限制(由指针大小限制)。 32位和64位系统之间的主要区别是指针的大小,在32位系统上,您只能使用32位指针,例如可以访问4294967296字节(4GB)。 系统保留其中一些,因此最终大约为2.5 GB。 在64位系统上,它更多,2 ^ 64 = 16 exabyte,在实践中为256 terabyte至4 petabyte。比您需要的要多得多。 如果您没有足够的内存(和交换空间),可能会崩溃。


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