所以,我有我想,当我用它做以释放其内容这个二维动态数组。但是我一直运行到析构函数后堆损坏。该代码工作正常(当然内存泄漏),如果我注释掉析构函数。 (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;    
} 

我不知道什么是错的代码。唯一的另一件事是别的地方,我这样做在一个循环崩溃发生的位置

FrameData myFrame;
std::vector<FrameData> frames;
...snipped...
frames.push_back(myFrame);

这不应引起任何问题,对不对?如果我记得正确的,使的push_back而不是存储指针或引用的副本。

PS。是的,我应该用向量。但我不能。

附加信息:

操作员=和拷贝构造没有限定。我想这是针对该问题的原因。

有帮助吗?

解决方案

您的问题是,你猜在这里:

FrameData myFrame;
std::vector<FrameData> frames;
...snipped...
frames.push_back(myFrame);

在矢量使您在推的元素的副本。你有什么你的拷贝构造函数和/或operator=为你的类?如果你没有定义,编译器会为您创建默认版本只是使你的类成员的副本。这将指针成员redgreenblue复制到新的实例。然后您复制时,它超出范围就会被破坏,从而导致指针旧实例被删除。然后复制到载体的一个将具有无效指针自从指针的目标因此删除。

一个好的经验法则是,如果您有任何原始指针的成员,那么你需要做一个拷贝构造函数和operator=将正确处理这种情况下,通过确保指针被赋予新的价值,而不是共享,或所有权在实例之间转移。

例如,在std::auto_ptr类有一个原始指针 - 拷贝构造的语义是将指针的所有权转移到目标

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

的另一种方式可以是使用载体把你的构件指针的位置 - 的构件指针简单地为您的阵列别名无论如何,所以该载体是一个很好的替代

其他提示

除非你有一个深拷贝构造函数和赋值操作符的FrameData类我的直觉是,编译器生成的拷贝构造函数用的push_back使用。自动生成的拷贝构造函数和赋值操作符会做一个成员复制,这将导致浅表副本在这种情况下。不幸的是你的析构函数不知道的副本,以便在复制过程中,有一个很好的机会,FrameData的临时副本被破坏,这将需要所有的数据吧。

在该过程再次调用以后,析构函数将导致双自由,加上其他的分配可能已经使用“自由”存储器的一部分。这看起来像从这里一个很好的理由堆损坏。

找到的问题,像这些通常是使用一个工具,如Valgrind的或纯化以查明问题的最佳方法。

<击>这不是一个问题的答案,只是一个观察。

由于您的帧数据可能会很大,以避免过多的复制,可能是更好的为你使用

std::vector<FrameData *> frames;

编辑: 正如其他人所指出的那样,这也将解决你的问题,崩溃

您即将进行的push_back一份正确的,但FrameData有一个合适的拷贝构造函数和赋值操作符?

另外,为什么剧组在这里:

delete[] ((uint8_t*) red[i]);

在C ++中,如果你必须使用C风格(或重新解释)投,代码几乎可以肯定是错误的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top