Question

I am dynamically allocating memory for an array in a function. My question is: once the function finishes running is the memory freed?

code:

void f(){
    cv::Mat* arr = new cv::Mat[1];
    ...
}
Was it helpful?

Solution

No, it is not. You must free it by calling

delete[] arr;

But you should ask yourself whether it is necessary to allocate dynamically. This would require no explicit memory management:

void f(){
    cv::Mat arr[1];
    ...
}

If you need a dynamically sized array, you could use an std::vector. The vector will internally allocate dynamically, but will take care of de-allocating it's resources:

void f(){
    std::vector<cv::Mat> arr(n); // contains n cv::Mat objects
    ...
}

OTHER TIPS

No, memory allocated using new is not automatically freed when the pointer goes out of scope.

However, you can (and should) use C++11's unique_ptr, which handles freeing the memory when it goes out of scope:

void f(){
    std::unique_ptr<cv::Mat[]> arr(new cv::Mat[1]);
    ...
}

C++11 also provides shared_ptr for pointers you might want to copy. Modern C++ should strive to use these "smart pointers", as they provide safer memory management with almost no performance hit.

No. Every call to new needs to be matched up with a call to delete somewhere.

In your case arr iteself is a variable with automatic storage duration. This means that arr itself will be destroyed when it goes out of scope. However the thing that arr points to does not, because that is a variable that does not have autoatic storage duration.

The fact that arr itself has automatic storage duration can be used to your advantage, by wrapping the raw pointer in a class that destroys the stored pointer when the automatic object is destroyed. This object utilizes an idion known as RAII to implement a so-called "smart pointer". Since this is a very common requirement in well-designed applications, the C++ Standard Library provides a number of smart pointer classes which you can use. In C++03, you can use

std::auto_ptr

In C++11 auto_ptr has been deprecated and replaced by several other better smart pointers. Among them:

std::unique_ptr std::shared_ptr

In general, it is a good idea to use smart pointers instead of raw ("dumb") pointers as you do here.

If what you ultimately need are dynamically-sized arrays, as supported by C99, you should know that C++ does not have direct support for them. Some compilers (notably GCC) do provide support for dynamically sized arrays, but these are compiler-specific language extensions. In order to have something that approximates a dynamically sized array while using only portable, Standards-compliant code, why not use a std::vector?

Edit: Assigning to an array:

In your comments you describe the way in which you assign to this array, which I have taken to mean something like this:

int* arr = new int[5];
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;

If this is the case, you can accomplish the same using vector by calling vector::operator[]. Doing this looks uses very similar syntax to what you've used above. The one real "gotcha" is that since vectors are dyanamically sized, you need to make sure the vector has at least N elements before trying to assign the element at position N-1. This can be accomplished in a number of ways.

You can create the vector with N items from the get-go, in which case each will be value-initialized:

vector<int> arr(5); // creates a vector with 5 elements, all initialized to zero
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;

You can resize the vector after the fact:

vector<int> arr; // creates an empty vector
arr.resize(5); // ensures the vector has exactly 5 elements
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;

Or you can use a variety of algorithms to fill the vector with elements. One such example is fill_n:

vector<int> arr; // creates empty vector
fill_n(back_inserter(arr), 5, 0);  // fills the vector with 5 elements, each one has a value of zero
arr[1] = 1;
arr[4] = 2;
arr[0] = 3;

No, of course not.

For every new you need precisely one delete.

For every new[] you need precisely one delete[].

Since you don't have the matching delete[], your program is broken.

(For that reason, the adult way of using C++ is not to use new or pointers at all. Then you don't have those problems.)

No. The array the allocated on the heap, you'll have to delete it before it goes out of scope:

void f() {

    cv::Mat * arr = new cv::Mat[1];

    // ...

    delete [] arr;

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top