3

我正在尝试保存一个充满指向 Circle 对象的指针的向量。有时 bad_alloc 捕获有效,但有时无效,然后我收到错误消息:

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

也许向量数组不能分配更多的内存......但是 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;
}

如果有人可以帮助我,那就太好了;)在此先感谢

4

3 回答 3

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";
}
于 2014-05-15T13:10:08.397 回答
1

通过任务管理器监控您的进程内存 - 您可能会消耗该进程允许的所有内存(取决于您的起点和 的大小Circle)。

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

于 2014-05-15T12:50:17.910 回答
0

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

其次,如果您以某种方式触发了未定义的行为(例如,通过取消引用NULL指针),您不一定会得到异常;根据语言规则,您不一定会得到任何有意义的行为

第三,正如已经在 Linux 上建议的那样,您可能会触发内存不足杀手。这不是真正符合标准的行为,但它是您在现实生活中可能遇到的行为。

于 2014-05-16T02:50:10.527 回答