使用析构函数删除动态对象? C ++

时间:2013-05-25 23:08:36

标签: c++ dynamic memory-management

我在整个程序中有一些面临类似问题的对象。一个例子:

我有一个Image类:

class Image
{
public:
    Image();
    Image(const Image& copy);
    ~Image();

    void loadimage(string filename);
    void saveimage(string filename);
    Image superimpose(const Image& ontop, Color mask);

    int getwidth();
    int getheight();
    Image operator=(const Image&);

protected:    
    Color** pixels;
    int width;
    int height;
    ImageLoader* loader;
};

它有一个复制构造函数:

Image::Image(const Image& copy)
{
    width = copy.width;
    height = copy.height;
    loader = copy.loader;

    pixels = new Color*[height];
    for(int i = 0; i < height; i++)
    {
        pixels[i] = new Color[width];
    }

    for(int h = 0; h < height; h++)
    {
        for(int w = 0; w < width; w++)
        {
            pixels[h][w] = copy.pixels[h][w];
        }
    }
}

颜色是结构:

struct Color
{
    unsigned int r;
    unsigned int g;
    unsigned int b;
};

我担心的是我创建了一个动态的二维Color结构数组,但我不确定何时何地删除它。我在我的Image析构函数中实现了以下内容,但我并不是100%确定它正在完成这项工作而我不确定如何检查它是否存在:

Image::~Image()
{
    for(int i = 0; i < height; i++)
    {
        delete[] pixels[i];
    }

    delete[] pixels;
    pixels = NULL;
}

我是否正确实现了内存释放?

3 个答案:

答案 0 :(得分:3)

没关系。

两点,您可以使用unique_ptrshared_ptr并摆脱自我删除内存。

其次,我更喜欢使用nullptr0代替NULL (虽然它是标准的)。此外,由于容器对象正在销毁,因此您无需将其成员设置为null。

最好的是使用std::vector

std::vector<std::vector<Color>> pixels;

...

Image::Image(const Image& copy)
{
    width = copy.width;
    height = copy.height;
    loader = copy.loader;

    pixels.resize(height);
    for (int i = 0; i < height; i++)
    {
        pixels[i].resize(width);
    }

    for(int h = 0; h < height; h++)
    {
        for(int w = 0; w < width; w++)
        {
            pixels[h][w] = copy.pixels[h][w];
        }
    }
}

答案 1 :(得分:2)

  

我是否正确实现了内存释放?

是。它是正确的。但是,您最好用vector of vectors替换2D动态数组,它自己管理内存,更安全,更不容易出错。

答案 2 :(得分:2)

我在这里看到缺少RAII以及潜在异常的问题,如bad_alloc,会使您的对象处于未定义状态。我会将memomry分配给一个为您管理内存的对象,因此当对象超出范围时,它将自行销毁。所述对象还应提供复制构造器,其深度复制存储器并允许您通过指向第一个字节的指针访问原始数据。 std :: vector具有所有这些属性。