3

I have an Image class and initially I do not know the image dimensions, so I just initialize a data_ pointer to be an array of size 0. Later when I find the image information I reinitialize data_ to a new size. Will this create any problem in memory? and is there a cleaner way to do this?

Below is the class I have written:

class Image
{
private:
    int numRows_, numCols_;
    unsigned char* data_;
public:
    Image() : numRows_(0), numCols_(0), data_(new unsigned char[0])
    {}
    void setData(int r, int c, unsigned char* data)
    {
        this->numRows_ = r;
        this->numCols_ = c;
        this->data_ = new unsigned char[r*c];
        for (int i = 0; i < r*c; i++)
        {
            this->data_[i] = data[i];
        }
    }
    int rows();
    int cols();
    unsigned char* data();
    ~Image();
};

Thanks in advance

Ijlal
  • 141
  • 1
  • 11

2 Answers2

7

This will in fact leak memory. The call to new allocates memory for the array, even if it is empty. As soon as you reassign data_, the previous array is leaked and can no longer be freed.

You can either make sure you delete[] any new[] you allocate, or just don't allocate an empty array and instead set data_ to nullptr until you have meaningful data to use.

An even better idea is don't allow the creation of an object in an invalid state, require the data in the constructor - see RAII:

In RAII, holding a resource is a class invariant, and is tied to object lifetime: resource allocation (or acquisition) is done during object creation (specifically initialization), by the constructor, while resource deallocation (release) is done during object destruction (specifically finalization), by the destructor.

If you do decide to keep setData, then as mentioned in comments, you also must make sure to delete[] existing data in setData before reassigning data_, in case the method is called more than once.

Rotem
  • 19,723
  • 6
  • 57
  • 101
  • Thanks @Rotem I'm going to use nullptr this time but just out of curiosity is it wise to call delete[] on private pointer `data_` using one of its public methods? I have a feeling that it should be avoided if possible. – Ijlal Jun 01 '17 at 11:34
  • @Ijlal Why, what kind of danger does that introduce? – Rotem Jun 01 '17 at 13:44
3

I think a cleaner way to do so will be using a vector:

std::vector<unsigned  char> v; // vector with size 0
v.resize(r*c);                 // after size is known, just resize
CIsForCookies
  • 10,156
  • 5
  • 36
  • 74