程序以std :: bad_alloc终止

r.v*_*r.v 4 c++ memory-management

我正在运行一个C++程序,它std::bad_alloc在任意点死亡,这取决于指定的输入.以下是关于该计划的一些观察/观点:

  • 对于较短的运行(运行时间取决于输入),程序正常完成.这个问题只适用于较大的运行.
  • 该程序没有任何可检测的内存泄漏.对于较小的运行,使用Valgrind/Memcheck检查了这一点.此外,我的整个代码没有任何指针(所有动态分配都由库完成,例如,在std::vector和中std::string;这些库类中的分配失败),因此内存泄漏极不可能.
  • 几个对象在循环中分配,然后移动到容器.其中一些对象在程序即将结束之前一直存在.
  • 我怀疑堆碎片可能是一个问题(参见C++程序死于std :: bad_alloc,但是valgrind报告没有内存泄漏)但我在64位系统上使用64位编译器(特别是带有g ++的Linux)和堆碎片在64位的土地让我相信堆碎片不能成为64位系统的问题.

还有什么我应该尝试的吗?任何可以帮助的特定工具?还有其他建议吗?

更新:最后证明虚拟内存已经受到限制ulimit -v.我后来忘了这件事,因此内存耗尽.将其重新设置以unlimited解决问题.

Mat*_*son 5

std::bad_alloc 意味着您请求的内存比可用内存多.

您可以遇到程序没有泄漏但仍然真正耗尽内存的情况:

vector<long> v;
long n = 0;
for(;;)
{
   v.push_back(n++);
}
Run Code Online (Sandbox Code Playgroud)

最终将耗尽你所拥有的任何机器中的所有可用内存 - 但它不会泄漏 - 所有内存都在向量中占用.显然,任何容器可以由做同样的事情,vector,list,map,其实并不重要.

Valgrind只找到你"放弃"分配的实例,而不是用当前可达内存填充系统的地方.

可笑的是上面的一种较慢形式 - 你在一些容器中存储的越来越多.它可能是您正在缓存的内容,或者您​​认为已删除它时未删除的内容.

观察应用程序上的内存量实际上是在一些监控程序中使用(Linux/Unix中的"top",Windows中的"任务管理器")并查看它是否实际增长.如果是这种情况,那么你需要弄清楚正在增长的是什么 - 对于一个大型程序来说,这可能很棘手(有些事情可能会成长,有些则不会......)

当然也有可能你突然得到一些不好的计算,例如,要求负数的元素T* p = new T[elements];会导致错误的alloc,因为元素被转换为无符号,而负无符号数是巨大的.

如果您可以在调试器中捕获bad_alloc,那么通常很容易发现这种情况,因为请求的大量数据new将非常明显.

在调试器中捕获异常通常应该有所帮助,尽管当你出错时你可能只为一个小字符串分配内存,如果你确实有泄漏的东西,那么这就是分配时的情况并不罕见它出错了.

如果您正在使用Unix的风格,您还可以加快错误查找,将应用程序允许使用的内存量设置为较小的大小,使用ulimit -m size(以千字节为单位)或ulimit -v size.