23

消息:

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 多次迭代后终止。上述函数仅在我的应用程序快结束时调用一次。我在调用上述函数之前调用了一个非常相似的函数,这不会导致问题。

4

2 回答 2

31

(从评论中移动/扩展)

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

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

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

于 2011-12-04T21:57:23.530 回答
3

我的问题原来是this->meshPoints.getNormalForVertex(i)访问一个长度小于this->meshPoints.getNumFaces() * 3. 所以它访问越界。

于 2011-12-06T08:44:18.463 回答