执行memcpy时内存泄漏

时间:2013-10-27 08:05:29

标签: c++ memory-leaks ffmpeg

我正在尝试编写一个处理ffmpeg的实用程序。一旦我需要将图像平面从一个指针复制到另一个指针。从AVPicture结构到我自己。 这是一些消息来源。

我自己的框架结构。在构造函数中分配的内存,在析构函数中取消分配

template <class DataType>
struct Frame
{
    DataType* data; //!< Pointer to image data
    int f_type; //!< Type of color space (ex. RGB, HSV, YUV)
    int timestamp; //!< Like ID of frame. Time of this frame in the video file
    int height; //!< Height of frame
    int width; //!< Width of frame

    Frame(int _height, int _width, int _f_type=0):
        height(_height),width(_width),f_type(_f_type)
    {
        data = new DataType[_width*_height*3];
    }

    ~Frame()
    {
        delete[] data;
    }
};

这是执行转换的主循环。如果注释了memcpy行,则根本没有内存泄漏。但如果我取消注释,则会出现内存泄漏。

for(int i = begin; i < end; i++)
{
    AVPicture pict;
    avpicture_alloc(&pict, PIX_FMT_BGR24, _width, _height);
    std::shared_ptr<Frame<char>> frame(new Frame<char>(_height, _width, (int)PIX_FMT_BGR24));

    sws_scale(ctx, frame_list[i]->data, frame_list[i]->linesize, 0, frame_list[i]->height, pict.data, pict.linesize);

    memcpy(frame->data,pict.data[0],_width*_height*3);

    //temp_to_add->push_back(std::shared_ptr<Frame<char>>(frame));

    avpicture_free(&pict);
}

我一直在尝试很多事情,例如:通过malloc分配内存并通过free释放内存,使用std :: copy和avpicture_layout(ffmpeg helper函数)将内存从pict复制到框架(在for循环中)。什么都没有帮助。 所以问题是:我忘了重要的事情吗?

我将感激每一个答案。

2 个答案:

答案 0 :(得分:1)

你确定它是一个泄漏,而不仅仅是你在内存中出现故障吗?

如果您拨打malloc()new,该语言将为您提供对内存的访问权限。然而,操作系统(在Windows,Linux或MacOS X等虚拟内存操作系统的情况下)实际上不会使页面成为任务工作集的一部分,直到您尝试对该内存执行某些操作。

如果您认为自己正在泄漏,因为memcpy()导致Windows流程资源管理器中的流程大小增加,这是一个糟糕的结论。即使您对象free()delete,流程大小也不一定会减少。

以这两个测试用例为例。两者显然都没有泄漏。

// test 1
int main()
{
    volatile int *data = (volatile int *)malloc( (1 << 24) * sizeof(int) );
    free((void *)data);

    // Spin until killed, so we're visible in the process explorer as long as needed
    while (1)
        ;
}

// test 2
int main()
{
    volatile int *data = (volatile int *)malloc( (1 << 24) * sizeof(int) );
    int i;

    for (i = 0; i < (1 << 24); i++)
        data[i] = i;

    free((void *)data);

    // Spin until killed, so we're visible in the process explorer as long as needed
    while (1)
        ;
}

我怀疑第二个将在进程资源管理器中显示更大的内存占用量。它应该超过64MB。

两个程序之间的区别在于第二个程序实际上写入了它分配的内存,因此迫使操作系统实际使页面可用于任务。一旦任务拥有页面,它通常不会将它们返回给操作系统。

(如果在上面的示例中确实发生了这种情况,请尝试较小的尺寸,例如(1 <&lt;&lt; 18)或其他东西。有时候malloc会变得聪明,但通常不会。“< / p>

答案 1 :(得分:0)

您的班级很容易在复制构造或作业上泄漏内存。您应该提供一个显式的复制构造函数和赋值运算符(至少禁止作为私有):

private:
    Frame(const Frame<T>& rhs);
    Frame<T>& operator=(const Frame<T>& rhs);