Reputation: 10172
I have a few objects throughout the program that are facing a similar issue. One example:
I have an Image class:
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;
};
It has a copy constructor:
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];
}
}
}
Color is a struct:
struct Color
{
unsigned int r;
unsigned int g;
unsigned int b;
};
My concern is that I create a dynamic two-dimensional array of Color structs, but I'm not sure when and where to delete it. I implemented the following in my Image destructor, but I'm not 100% certain that it's doing the job and I'm not sure how to check if it does:
Image::~Image()
{
for(int i = 0; i < height; i++)
{
delete[] pixels[i];
}
delete[] pixels;
pixels = NULL;
}
Am I implementing the memory deallocation correctly?
Upvotes: 0
Views: 2100
Reputation: 56549
It's OK.
Two points, you can use unique_ptr
or shared_ptr
and get rid of self deleting the memory.
Second is, I prefer use nullptr
or 0
instead of NULL
(although it's standard). Moreover, since the container object is destroying, you don't need to set its member to null.
And the best is using 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];
}
}
}
Upvotes: 3
Reputation: 7604
I see a lack of RAII here and problems with potential exceptions thrown like bad_alloc which will leave your object in an undefined state. I would allocate the memomry in an object that manages memory for you and so when the object is out of scope it will destroy itself. Said object should also provide a copy construtor that deep copies memory and allows you to access the raw data through a pointer to the first byte. std::vector has all these attributes.
Upvotes: 2
Reputation: 23664
Am I implementing the memory deallocation correctly?
Yes. It is correct. However, you'd better replace the 2D dynamic array with vector of vectors
, which manages memory by itself, safer and less error prone.
Upvotes: 2