简体   繁体   中英

How can i free dynamic memory that i allocated inside a “get” function?

I'm creating a function that will return an array that i have to allocate memory for, but i can't find a way to make sure that memory will be deleted at the end of the program.

Here's the function:

int* RGB::getColor() const{
    int* arr = new int[3];

    arr[0] = red;
    arr[1] = green;
    arr[2] = blue;

    return arr;
}

Here's an example for its use:

int main(){
    int green;
    RGB test(50, 100, 150);

    green = test.getColor()[1];
}

Since it's not an object i can't delete anything inside the RGB's class destructor. How can i make sure the memory is deleted at the end of the "getColor()" function use? Thanks.

I guess this can save you some trouble:

class RGB
{
public:
    RGB(int r, int g, int b)
    {
        colors[0] = r;
        colors[1] = g;
        colors[2] = b;
    }

    int operator[](uint index)
    {
        // you can check index is not exceeding 2, if you want
        return colors[index];
    }

    int getColor(uint index)
    {
        // you can check index is not exceeding 2, if you want
        return colors[index];
    }

private:
    int colors[3];
};

int main(){

    RGB test(50, 100, 150);
    int green = test[1];
    // int green = test.getColor(1); // or you really want to use it this way
}

A modified version trying to achieve OP's request in comment:

struct Color
{
    int values[3];

    int operator[](uint index) const
    {
        // you can check index is not exceeding 2, if you want
        return values[index];
    }
};

class RGB
{
public:
    RGB(int r, int g, int b)
    {
        color.values[0] = r;
        color.values[1] = g;
        color.values[2] = b;
    }

    Color getColor() const
    {
        return color;
    }

private:
    Color color;
};

int main() {
    RGB test(50, 100, 150);
    int green = test.getColor()[1]; // no need to worry about memory management!
}

And actually it might be better if:

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

    enum Type
    {
        RED = 0,
        GREEN = 1,
        BLUE = 2,
    };

    int operator[](Type type) const
    {
        return values[type];
    }
};

class RGB
{
public:
    RGB(int r, int g, int b)
    {
        color.r = r;
        color.g = g;
        color.b = b;
    }

    Color getColor() const
    {
        return color;
    }

private:
    Color color;
};

int main() {
    RGB test(50, 100, 150);
    int green = test.getColor()[Color::GREEN];
}

How can i make sure the memory is deleted at the end of the "getColor()" function use?

You can do that by capturing the result of the call and calling delete[] on it. This solution works, but it has problems that can be avoided.

Solution 1:

RGB test(50, 100, 150);

int *values = test.getColor(); // store result in variable here
green = values[1];
delete []values; // and release the memory here

This implementation is problematic, because it imposes responsibilities on the client code (ie if you don't call delete, you have leaks).

Here's an alternative solution:

Solution 2:

typedef std::tuple<int,int,int> RGBValue;

RGBValue RGB::getColor() const{
    return RGBValue{ red, green, blue };
}

auto green = std::get<1>( test.getColor() );

Since it's not an object i can't delete anything inside the RGB's class destructor.

Not being an object is not the issue. C-style arrays that have been allocated with new[] are freed with delete[] . But you should not free it in RGB 's destructor, because you've passed it outside the object and it might still be used.

You can free the memory with your current design:

int* colors = test.getColor();
green = colors[1];
delete[] colors;

But as you can see, it's not very good, because the caller must always remember to free something that they never allocated themselves.

Simplest design would be to return an instance of a container class which takes care of the memory:

#include <array>

std::array<int, 3> RGB::getColor() const{
    return {red, green, blue};
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM