2

I'm new to C++ and I have a problem with memory management.

I have one function a() that calls 3 functions (b(), c(), d()), each one of which returns a dynamically allocated array of MyClass objects:

void a(){
    MyClass * one=b();
    MyClass * two=c();
    MyClass * three=d();
    //operate with 3 array (one, two and three)
    delete [] one;
    delete [] two;
    delete [] three;
}

MyClass * b(){
    MyClass * array=new MyClass[2000];
    //many operations on array
    return array;
}

MyClass * c(){
    MyClass * array=new MyClass[2000];
    //many operations on array
    return array;
}

MyClass * d(){
    MyClass * array=new MyClass[2000];
    //many operations on array
    return array;
}

After many operations in a() I must delete the 3 arrays that I created with the 3 functions. If I do it using the 3 delete [] expressions like those in the code above, is it ok?

I asked myself this question because I think that this code deallocates everything correctly, but analyzing the memory allocation of my c++ program I see no evidence of this deletion.

2
  • No it is not ok. If you create with new[] you should use delete[] Commented May 27, 2018 at 9:19
  • @KillzoneKid Yes, you are right but I forgot to write it in my question, but in the code I correctly do with delete[] Commented May 27, 2018 at 9:21

2 Answers 2

5

For reliable memory-management you should use smart pointers such as std::unique_ptr. So when your function is returning a dynamically allocated value it should instead return std::unique_ptr to that value to make sure that this value will be deallocated.

std::unique_ptr<MyClass[]> array(new MyClass[2000]);

In your case however you should consider using std::vector instead of raw array.

Sign up to request clarification or add additional context in comments.

Comments

3

Yes, what you're doing is correct.

However, note that manual memory management is prone to bugs, be it memory leaks or double deletion. It's much better to forget about naked new and especially delete, and instead use RAII classes for handling this safely.

In your case, you should replace the pointers to dynamically-allocated arrays with std::vector. std::vector is the way to spell "dynamically allocated array" in C++. Once you do that, you will know that the vector will take care of deallocating the memory correctly, even in the presence of exceptions.

This is what your code could look like with std::vector:

void a(){
    auto one=b();
    auto two=c();
    auto three=d();
    //operate with 3 array (one, two and three)

    //nothing to do here, the vectors will deallocate memory correctly when they go out of scope
}

std::vector<MyClass> b(){
    std::vector<MyClass> array(2000);
    //many operations on array
    return array;
}

std::vector<MyClass> c(){
    std::vector<MyClass> array(2000);
    //many operations on array
    return array;
}

std::vector<MyClass> d(){
    std::vector<MyClass> array(2000);
    //many operations on array
    return array;
}

As for why you can't see effects of the deallocation: memory freed by delete need not be immediately returned to the operating system. Quite often, the C++ runtime will keep hold of it and use it to satisfy future allocation requirements of your program.

7 Comments

Thanks for the answer. Probably I can't see the effect of the deallocation for the reason that you explain.
PS. for "dynamically allocated array" I didn't mean the possibility to grow (make smaller) dynamically the array but I mean the allocation on heap memory to use pointer to this data structure. So to do the combo: Heap memory+array that can resize dynamically I must use a syntax like this: std::vector * myArray=new std::vector(2000); Is it true?
@Antonio1996 No, of course not. Just do std::vector<MyClass> myArray(2000);. The vector's data is always allocated dynamically, and that's what I mean in the answer too.
Ahh ok, so if I create std::vector<MyClass> myArray(2000); , when myArray go out of scope, automatically will be called destructor of vector and destructor for all of my MyClass objects? But with this situation when myArray go out of scope I lose all. If I want the freedom to decide when delete it I can use a pointer of std::vector<MyClass>? I'm confused :(
@Antonio1996 Not really; using a std::vector<T>* is extremely rare. Allocating the vector itself dynamically (that is, new std::vector<T>) is even rarer. Normal C++ code simply does not need constructs like that.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.