使用new分配大块内存

时间:2009-02-26 12:28:01

标签: c++ memory new-operator bad-alloc

我需要使用new来分配大块内存。

我坚持使用new,因为我正在为两部分应用程序的生产者方面编写一个模拟器。实际的生产者代码正在分配这些大块,我的代码有责任删除它们(在处理它们之后)。

有没有办法可以确保我的应用程序能够从堆中分配如此大量的内存?我可以将堆设置为更大的尺寸吗?

我的情况是64块288000字节。有时我得到12分配,有时我得到27分配。我收到了std :: bad_alloc异常。

这是:C ++,Linux上的GCC(32位)。

5 个答案:

答案 0 :(得分:9)

关于C ++ / GCC / Linux(32位)中的 new ......

已经有一段时间了,它依赖于实现,但我相信 new 会在幕后调用 malloc() Malloc(),除非您要求超出流程地址空间或超出指定( ulimit / getrusage )限制的内容,否则不会失败。即使您的系统没有足够的RAM + SWAP。例如:我认为,在具有256Meg RAM + 0 SWAP的系统上, malloc(1gig)将成功。

但是,当您使用该内存时,内核通过延迟分配机制提供页面。此时,当您第一次读取或写入该内存时,如果内核无法为您的进程分配内存页面,则会终止您的进程。

当您的同事核心泄漏缓慢时,这可能是共享计算机上的问题。特别是当他开始淘汰系统过程时。

因此,您看到std :: bad_alloc异常的事实是“有趣的”。

现在 new 将在分配的内存上运行构造函数,在返回之前触及所有这些内存页面。根据实现情况,可能正在捕获内存不足的信号。

您是否尝试使用普通的o'l malloc

您是否尝试过运行“免费”计划?你有足够的内存吗?

正如其他人所建议的那样,你有没有检查过 limit / ulimit / getrusage() for hard&软约束?

您的代码究竟是什么样的?我猜是新的ClassFoo [N] 。或者 new char [N]

什么是 sizeof(ClassFoo)?什么是 N

对于大多数现代机器来说,分配64 * 288000(17.58Meg)应该是微不足道的......你是在嵌入式系统上运行还是其他特殊的东西?

或者,您是否使用自定义分配器进行链接?您的班级是否有自己的分配器?

您的数据结构(类)是否将其他对象作为其构造函数的一部分进行分配?

有人篡改了您的图书馆吗?你有多个编译器安装?您使用错误的包含或库路径吗?

您是否链接过时的目标文件?您只需要重新编译所有源文件吗?

你能创建一个简单的测试程序吗?只需几行代码即可重现错误?或者你的问题在其他地方,只出现在这里?

-

为了它的价值,我已经在gbit的32位linux下用 new 分配了超过2gig的数据块。你的问题出在其他地方。

答案 1 :(得分:4)

你可能受到过程'ulimit的限制;运行ulimit -a并检查虚拟内存和数据段大小限制。除此之外,您可以发布您的分配代码,以便我们可以看到实际发生了什么吗?

答案 2 :(得分:1)

更新

我已修复了数组索引错误,现在正在正确分配。

如果我不得不猜测......我正在走遍我的堆,并且正在搞乱malloc的数据结构。 (??)

答案 3 :(得分:0)

我建议在程序启动时分配所有内存,并使用placement new来定位缓冲区。为什么这种做法?好吧,你可以手动跟踪碎片等。没有可移植的方法来确定可以为您的进程分配多少内存。我很肯定有一个特定于Linux的系统调用,可以获得这些信息(不能想到它是什么)。祝你好运。

答案 4 :(得分:0)

当您在不同时间运行程序时获得不同的行为这一事实使我认为分配代码不是真正的问题。相反,其他人正在使用记忆而你是金丝雀发现它丢失了。

如果您的计划中有“其他人”,您应该可以使用Valgrind找到它。

如果其他人是另一个程序,你应该能够通过去另一个runlevel来确定(虽然你不一定知道罪魁祸首)。