【问题标题】:"std::bad_alloc": am I using too much memory?“std::bad_alloc”:我使用了太多内存吗?
【发布时间】:2012-01-12 19:24:33
【问题描述】:

消息:

terminate called after throwing an instance of 'std::bad_alloc'
what():  std::bad_alloc

我查看了 gdb 回溯,这是我自己实现的最低级别的方法:

/*
 * get an array of vec3s, which will be used for rendering the image
 */
vec3 *MarchingCubes::getVertexNormalArray(){
    // Used the same array size technique as getVertexArray: we want indices to match     up
    vec3 *array = new vec3[this->meshPoints.getNumFaces() * 3]; //3 vertices per face

    int j=0;
    for (unsigned int i=0; i < (this->meshPoints.getNumFaces() * 3); i++) {
        realVec normal = this->meshPoints.getNormalForVertex(i);
 //     PCReal* iter = normal.begin();

        if (normal.size() >= 3) {
            array[j++] = vec3(normal[0], normal[1], normal[2]);
        }
        cout << i << " ";
    }

    return array;
}

您在上面看到的 cout 语句表明它在 7000 多次迭代后终止。 上述函数仅在我的应用程序快结束时调用一次。我在调用上述之前调用了一个非常相似的函数,这不会导致问题。

【问题讨论】:

  • 你有没有用delete[]释放这个函数返回的数组?
  • meshPoints.getNumFaces() 有多大? vec3 有多大?
  • 哎呀,你有大量的内存泄漏。顺便说一句,您应该使用smart pointers 或标准容器;你应该避免在 C++ 中完全手动管理内存,你的代码不会是异常安全的,而且你总是会冒内存泄漏的风险。
  • 在数组返回之前不要删除它,当不再需要它时应该删除它。也就是说,在调用函数的代码中的某处。把它想象成一块黑板:你在黑板上写数据,但你从不擦黑板来为新数据腾出位置(delete[])。如果你这样做的时间足够长,有时黑板上就没有位置了。但是你不应该从黑板上擦掉你仍然需要的东西;只有不再需要的东西。
  • 另一个想法,完全不同的方向:您是否检查过j 始终低于meshPoint.getNumFaces()*3?由于缓冲区溢出覆盖了基本堆结构,您可能会收到bad_alloc

标签: c++ bad-alloc


【解决方案1】:

(从 cmets 移动/扩展)

由于您每次都在分配一个新数组而不释放它,因此您会出现大量内存泄漏,即您继续向系统请求内存而从未将其归还。最终堆上的空间完成,在下一次分配时,你得到的只是一个std::bad_alloc 异常。

“C 风格”的解决方案是记住在不再需要时释放此类内存(使用 delete[]),但是,这 (1) 容易出错(例如,如果您有多个函数内部的返回路径)和(2)潜在的异常不安全(如果有异常,每条指令都将成为潜在的返回路径!)。因此,应该避免这种方式。

惯用的 C++ 解决方案是使用 smart pointers - 封装指针并在销毁相关内存时释放相关内存的小对象 - 或标准容器,它们或多或少地做同样的事情,但具有复制语义等等花里胡哨(包括在其中存储数组的大小)。

【讨论】:

    【解决方案2】:

    我的问题原来是this-&gt;meshPoints.getNormalForVertex(i) 访问了一个长度小于this-&gt;meshPoints.getNumFaces() * 3 的数组(或向量,我不记得了)。所以它访问越界了。

    【讨论】:

    • 这里不解释,std::bad_alloc异常:operator new和operator new[]的标准定义在分配请求的存储空间失败时抛出的异常类型。
    猜你喜欢
    • 1970-01-01
    • 2012-01-17
    • 2017-07-04
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 2014-09-20
    • 2015-12-03
    相关资源
    最近更新 更多