在C++中删除2D动态数组的问题(最终存储在向量中)

Ext*_*kun 1 c++ multidimensional-array dynamic-arrays

所以我有这个2d动态数组,当我完成它时,我想要释放内容.但是我在析构函数后继续遇到堆损坏.如果我注释掉析构函数,代码工作正常(当然有内存泄漏).(Visual Studio 2005)

FrameData::FrameData(int width, int height)
{
    width_ = width;
    height_ = height;

    linesize[0] = linesize[1] = linesize[2] = linesize[3] = 0;

    // Initialise the 2d array
    // Note: uint8_t is used by FFMPEG (typedef unsigned char uint8_t)
    red = new uint8_t* [height];
    green = new uint8_t* [height];
    blue = new uint8_t* [height];

    for (int i=0; i < height; i++)
    {
        red[i] = new uint8_t [width];
        green[i] = new uint8_t [width];
        blue[i] = new uint8_t [width];
    }       
}

FrameData::~FrameData()
{

    // Delete each column
    for (int i=0; i < height_; i++)
    {           
        delete[] ((uint8_t*) red[i]);
        delete[] ((uint8_t*)green[i]);
        delete[] ((uint8_t*)blue[i]);       
    }

    // Final cleanup
    delete[] red;
    red = NULL;

    delete[] green;
    green = NULL;

    delete[] blue;
    blue = NULL;    
} 
Run Code Online (Sandbox Code Playgroud)

我不知道代码有什么问题.唯一的另一件事是在其他地方,我在发生崩溃的循环中做到了这一点

FrameData myFrame;
std::vector<FrameData> frames;
...snipped...
frames.push_back(myFrame);
Run Code Online (Sandbox Code Playgroud)

这不应该造成任何问题,对吗?如果我记得正确,push_back会复制而不是存储指针或引用.

PS.是的,我应该使用矢量.但我不被允许.

附加信息:

未定义operator =和复制构造函数.我猜这是问题的原因.

180*_*ION 5

你在这里猜到的问题是:

FrameData myFrame;
std::vector<FrameData> frames;
...snipped...
frames.push_back(myFrame);
Run Code Online (Sandbox Code Playgroud)

该向量会复制您推送的元素.您对复制构造函数和/或operator=类有什么作用?如果您没有定义,则编译器为您创建的默认版本只会复制您的类的成员.这将复制指针成员red,green并复制blue到新实例.然后,当它超出范围时,将复制您复制的旧实例,从而导致删除指针.您复制到向量中的那个将具有无效指针,因为指针的目标因此被删除.

一个好的经验法则是,如果你有任何原始指针成员,那么你需要制作一个复制构造函数,并operator=通过确保指针被赋予新值而不是共享,或者所有权被转移来正确处理这种情况实例之间.

例如,std::auto_ptr类具有原始指针 - 复制构造函数的语义是将指针的所有权转移到目标.

boost::shared_ptr类有一个原始指针-语义是通过引用计数的装置共享所有权.这是处理std::vectors包含指向类的指针的好方法- 共享指针将控制您的所有权.

另一种方法可能是使用向量来代替你的成员指针 - 成员指针只是你的数组的别名,所以向量是一个很好的替代品.