简体   繁体   English

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

[英]C++ Memory Error on Delete - Debug Assertion Failed

I am trying to add a set of new ModelImages to a vector, and am getting an error, Debug Assertion Failed, Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse). 我正在尝试向向量添加一组新的ModelImages,并且收到错误,Debug Assertion Failed,Expression:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)。 This occurs when trying to delete the second ModelImage that is generated. 尝试删除生成的第二个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;
}

The constructor and destructor, and copy and swap funcitons, are as follows: 构造函数和析构函数以及复制和交换功能如下:

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);
}

Just before trying to delete the second ModelImage, looking at the vector ModelImages shows that the two ModelImages in the vector have the same assigned memory addresses for the distance, intensity, derivX, derivY arrays. 在尝试删除第二个ModelImage之前,查看向量ModelImages显示向量中的两个ModelImages具有相同的距离,强度,deriX,derivY数组的内存地址。

Any help is appreciated, thanks. 任何帮助表示赞赏,谢谢。

This is likely due to you not having a copy constructor. 这可能是由于您没有复制构造函数。

Create a copy constructor that makes copies of the memory that your pointers are referencing. 创建一个复制构造函数,复制指针引用的内存。

When using std containers, they usually will create copies of your object as you insert. 使用std容器时,它们通常会在您插入时创建对象的副本。 As you have no copy constructor, all your member pointers end up pointing to the same memory address because it's simply doing a member-wise copy of your data. 由于您没有复制构造函数,所有成员指针最终都指向相同的内存地址,因为它只是在执行成员方式的数据副本。 Once one of the temporary copies is destructed, (or when you call delete on the original object after the insert) the memory of the object inserted has had it's memory deleted from under it. 一旦其中一个临时副本被破坏,(或在插入后在原始对象上调用delete时),插入对象的内存即已从其下方删除。

My first guess is that you don't have a copy constructor defined. 我的第一个猜测是您没有定义副本构造函数。 The vectors' push_back will default copy construct your ModelImage which will simply copy the member pointers but not reallocate the memory they point to. 向量' push_back将默认复制构造您的ModelImage ,它将简单地复制成员指针但不重新分配它们指向的内存。 However, these references will be gone after the original objects are deleted. 但是,删除原始对象后,这些引用将会消失。

Hint: A copy constructor is something like: 提示:复制构造函数类似于:

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

Not to confuse with the assignment operator== 不要与赋值operator==混淆

Why do you do create these ModelImage s dynamically anyway (if you throw them right away)? 为什么无论如何ModelImage动态创建这些ModelImage (如果立即将它们扔掉)? And why don't you take vector<float>(nPixels) instead of new float[nPixels] ? 为什么不采用vector<float>(nPixels)而不是new float[nPixels]

It's not clear from what you've posted whether or not you have a proper copy constructor and assignment operator for the following members: 从您发布的内容来看,您是否拥有适合以下成员的复制构造函数和赋值运算符并不清楚:

distance
intensity
derivX
derivY

If not, you need those. 如果没有,你需要那些。 (see Rule of three (C++ programming) for a bit more information). (有关更多信息,请参见三则规则(C ++编程) )。

A better alternative would be to use std::vector<double> for those data members. 更好的选择是对这些数据成员使用std::vector<double> That way copying, assignment, and destruction would all be handled automatically. 这样,复制,分配和销毁都将自动处理。 You'd still want to construct them to have the proper number of elements. 您仍然希望将它们构造为具有适当数量的元素。

I'm assuming that you have all of the arrays defined as pointers in the class. 我假设您已将所有数组定义为类中的指针。 The default copy copies the values of the pointer meaning that when you delete the pointer in the outer function you delete the underlining memory. 默认副本复制指针的值,这意味着当您删除外部函数中的指针时,您将删除下划线内存。

Just a couple of suggestions 只是几个建议

-Utilize Vector instead of a float * std::vector has copy and move constructors defined allread -使用Vector而不是float * std :: vector具有复制和移动定义为allread的构造函数

-The loop doesn't need to use the free store at all value semantics and coping are fully supported and less error prone. - 循环不需要在所有值语义中使用免费存储,并且完全支持应对并且不易出错。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM