【问题标题】:C++ Memory Error on Delete - Debug Assertion Failed删除时出现 C++ 内存错误 - 调试断言失败
【发布时间】:2012-03-06 05:42:38
【问题描述】:

我正在尝试将一组新模型图像添加到向量中,但出现错误,调试断言失败,表达式:_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 表明向量中的两个 ModelImage 为距离、强度、derivX、derivY 数组分配了相同的内存地址。

感谢您的帮助。

【问题讨论】:

  • 我确实有一个复制构造函数,并且刚刚在此处包含了它。
  • 我在您的更新中没有看到复制构造函数。它的签名类似于ModelImage(ModelImage const&amp; other);
  • 感谢您明确指出 - 我没有意识到我没有实现复制和交换习语的复制部分,并且认为我已经实现了。我第一次与他们合作。
  • 你为什么不做ModelImages.push_back(ModelImage(MOD_WIDTH,MOD_HEIGHT));?如果您要按值将图像存储在向量中,则循环内的动态分配是不必要的,而且很奇怪。

标签: c++ memory vector


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    从您发布的内容中不清楚您是否为以下成员提供了适当的复制构造函数和赋值运算符:

    distance
    intensity
    derivX
    derivY
    

    如果没有,您需要这些。 (更多信息请参见Rule of three (C++ programming))。

    更好的选择是对这些数据成员使用std::vector&lt;double&gt;。这样,复制、分配和销毁都将自动处理。您仍然希望构建它们以具有适当数量的元素。

    【讨论】:

      【解决方案3】:

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

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

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

      不要与分配operator==混淆

      你为什么要动态创建这些ModelImages(如果你马上扔掉它们)? 为什么不使用vector&lt;float&gt;(nPixels) 而不是new float[nPixels]

      【讨论】:

      • 动态创建它们,因为我尝试了 ModelImage mI(MOD_WIDTH,MOD_HEIGHT); ModelImages.push_back(*mI);这也没有用。
      • 你试过ModelImages.push_back( ModelImage(MOD_WIDTH, MOD_HEIGHT) ); 吗?但这也不能解决您与复制构造函数的问题...
      【解决方案4】:

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

      只是一些建议

      -使用向量而不是浮点数 * std::vector 定义了复制和移动构造函数 allread

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

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

      【讨论】:

        猜你喜欢
        • 2011-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-26
        • 2015-03-02
        • 1970-01-01
        相关资源
        最近更新 更多