C ++ Vector catch调整内存泄漏

时间:2014-05-15 12:48:13

标签: c++ vector alloc bad-alloc

我正在尝试保存一个充满指向Circle对象的指针的向量。 有时bad_alloc catch会起作用,但有时它不起作用,然后我收到错误消息:

  

此应用程序已请求Runtime以不寻常的方式终止它。   请联系应用程序的支持团队获取更多信息。“

也许向量数组不能分配更多内存......但是bad_alloc没有捕获它。

Circle *ptr;
vector<Circle*> ptrarray;

try{
  for (long long i = 0; i < 80000000; i++) {
    ptr = new Circle(1,i);
    ptrarray.push_back(ptr);
  }
}catch(bad_alloc &ba){
  cout << "Memory Leak" << endl;
}

如果有人可以帮助我会很棒;) 提前致谢

3 个答案:

答案 0 :(得分:2)

假设进程可能实际上不访问所有页面,许多操作系统将允许进程请求比虚拟内存支持更多的虚拟地址(名义上可用的内存)。众所周知,这允许稀疏阵列在这样的系统上实用。但是,当您访问每个页面时,CPU会生成一个中断,并且操作系统必须找到支持该页面的物理内存(如果已配置,也会交换到非RAM交换磁盘/文件等) - 当所有选项都耗尽时(或者有时候操作系统危险地接近极限,并且一些保护过程决定杀死某些进程比让已知的关键进程开始失败更好,你可能会得到像你所观察到的错误。最终,在C ++级别上无法控制它。您可以快速预订和写入所有页面,这样您在进行所有处理之前可能会失败,但即使这样,您也可能会在极低的内存情况下被终止。


另外,如果按值存储它们,您可以在内存中放入更多的圆圈。也就是说,如果sizeof(Circle) > sizeof(Circle*)和碎片限制您,则可能不会,在这种情况下,您可能会尝试std::deque。无论如何:

try
{
    std::vector<Circle> array;
    array.reserve(80000000);
    for (long long i = 0; i < 80000000; i++) {
        array.emplace_back(1, i);
}
catch (const bad_alloc& ba)
{
    std::cerr << "Memory Exhaustion\n";
}

答案 1 :(得分:1)

通过任务管理器监控您的进程内存 - 您可能会占用该进程允许的所有内存(等待您的起点和Circle的大小)。

如果你在Win32机器上,那么你有大约2GB的进程内存空间用于此操作

答案 2 :(得分:0)

首先,您如何确定唯一可能引发的异常是std::bad_alloc?我强烈建议您在catch (...)阻止后添加catch (const bad_alloc&)阻止,以确认您是对的。当然,对于catch (...),你不会知道被抓到的是什么,只是它不是bad_alloc

其次,如果以某种方式触发未定义的行为(例如,通过解除引用NULL指针),则不一定会得到异常; you won't necessarily get any behavior that makes sense according to the language rules

第三,正如已经建议的那样on Linux you might be triggering the out of memory killer。它不是真正符合标准的行为,但它是您在现实生活中可能遇到的行为。