删除时C ++内存错误 - 调试断言失败

时间:2012-02-14 20:47:30

标签: c++ memory vector

我正在尝试向矢量添加一组新的ModelImages,并且收到错误,Debug Assertion Failed,Expression:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)。尝试删除生成的第二个ModelImage时会发生这种情况。

std::vector<ModelImage> ModelImages;

for(int n=0;n<nParamSets;n++)
{
    ModelImage* mI = new ModelImage(MOD_WIDTH,MOD_HEIGHT);
    ModelImages.push_back(*mI);
    delete mI;
}

构造函数和析构函数以及复制和交换函数如下:

ModelImage(int _width, int _height)
{
    width = _width;
    height = _height;
    nPixels = width*height;
    distance =  new float[nPixels];
    intensity = new float[nPixels];
    derivX =    new float[nPixels];
    derivY =    new float[nPixels];
    maxDistance = 0.0f;
    minDistance = 0.0f;
}

~ModelImage()
{
    delete [] derivX;
    delete [] derivY;
    delete [] distance;
    delete [] intensity;
}

ModelImage& operator=(ModelImage other)
{
    swap(*this, other);
    return *this;
} 

friend void swap(ModelImage& first, ModelImage& second)
{
    using std::swap;
    swap(first.derivX,second.derivX);
    swap(first.derivY,second.derivY);
    swap(first.distance,second.distance);
    swap(first.intensity,second.intensity);

    swap(first.nPixels,second.nPixels);
    swap(first.width,second.width);
    swap(first.height,second.height);
}

在尝试删除第二个ModelImage之前,查看向量ModelImages显示向量中的两个ModelImages具有相同的距离,强度,deriX,deriY数组的内存地址。

感谢任何帮助,谢谢。

4 个答案:

答案 0 :(得分:2)

这可能是因为你没有复制构造函数。

创建一个复制构造函数,复制指针所引用的内存。

使用std容器时,它们通常会在插入时创建对象的副本。由于您没有复制构造函数,所有成员指针最终都指向相同的内存地址,因为它只是在执行成员方式的数据副本。一旦一个临时副本被破坏,(或者在插入后对原始对象调用delete),插入的对象的内存就会从其下面删除它的内存。

答案 1 :(得分:1)

我的第一个猜测是你没有定义复制构造函数。向量'push_back将默认复制构造您的ModelImage,它将简单地复制成员指针但不重新分配它们指向的内存。 但是,删除原始对象后,这些引用将会消失。

提示:复制构造函数类似于:

ModelImage(const ModelImage& orig) {
  // appropriately reinitialize from orig
}

不要与作业operator==

混淆

为什么你要动态创建这些ModelImage(如果你马上扔掉它们)? 为什么不采用vector<float>(nPixels)代替new float[nPixels]

答案 2 :(得分:0)

目前尚不清楚您发布的内容是否为以下成员提供了正确的复制构造函数和赋值运算符:

distance
intensity
derivX
derivY

如果没有,你需要那些。 (有关更多信息,请参阅Rule of three (C++ programming)。)

更好的选择是对这些数据成员使用std::vector<double>。这样,复制,分配和销毁都将自动处理。你仍然想要构造它们以拥有适当数量的元素。

答案 3 :(得分:0)

我假设您已将所有数组定义为类中的指针。默认副本复制指针的值,这意味着当您删除外部函数中的指针时,您将删除下划线内存。

只是一些建议

-Utilize Vector而不是float * std :: vector有复制和移动构造函数定义allread

- 循环不需要在所有值语义中使用免费存储,并且完全支持应对并且不易出错。

 for(int n=0;n<nParamSets;n++)
 {       
     ModelImages.push_back( ModelImage(MOD_WIDTH,MOD_HEIGHT));
 }