2

When an array is created on the heap inside a function is it necessary to delete the array in the main function? Consider, this program:

#include "stdafx.h"
#include <iostream>

using namespace std;

int * return_array() {
    int* my_array = new int[10];
    my_array[0] = 10;
    return my_array;
}

int main()
{
    int * returned_array = return_array();
    cout << returned_array[0];
    delete[] returned_array;
    return 0;
}

This line: int* my_array = new int[10]; is it necessary to delete in the main program? I find that doing this every time will hard to maintain and get right.

Luke101
  • 56,845
  • 75
  • 204
  • 330

2 Answers2

5

Yes, in the code that you wrote, a call to delete[] is necessary after each call to return_array() because it is allocating new memory on the heap, which is not automatically reclaimed. Unlike Java and other higher level languages, C++ does not have a garbage collector. Failure to call delete[] will lead to memory leaks and an ever growing heap size.

As indicated by @Ron in the comments, a viable alternative is to use an std::vector<int> (if the array will never need to grow, then see also std::array). While the vector will internally use heap allocations, it also manages them automatically for you so that when they go out of scope their memory is automatically reclaimed.

#include <vector>

std::vector<int> return_vector() {
    std::vector<int> my_vector(10);
    my_array[0] = 10;
    return my_array;
}

int main()
{
    std::vector<int> returned_vector = return_vector();
    std::cout << returned_vector[0];
    return 0; // vector internal memory is reclaimed
}
Nathan
  • 4,287
  • 1
  • 26
  • 34
  • Re. the last paragraph, the compiler may decide to elide the copy completely. If not, then it is may use move semantics. The criteria for allowing move semantics are less restrictive than for copy elision, and, unlike copy elision, moving if the conditions are right is not optional. – juanchopanza Jun 30 '18 at 20:12
  • @juanchopanza I wasn't aware that the compiler preferred move over copy. That's good to know! – Nathan Jun 30 '18 at 20:14
  • Last paragraph is now wrong. Copy elision pre-dates C++11. – juanchopanza Jun 30 '18 at 20:18
  • arg.... I'm just dropping the last paragraph because I apparently don't understand elision. It isn't terribly relevant to the question anyway. Reading up on it at https://en.cppreference.com/w/cpp/language/copy_elision – Nathan Jun 30 '18 at 20:20
  • 1
    @juanchopanza Is the relevant elision above NVRO (named value return optimization)? There is neither a move nor a copy, but rather the vector `my_vector` inside `return_vector()` is allocated at the address of `returned_vector`? (e.g. "When that local object is constructed, it is constructed directly in the storage where the function's return value would otherwise be moved or copied to." from the above linked cppreference.com copy_elision article) – Nathan Jun 30 '18 at 20:28
  • Partially, What is missing is the conditions for NRVO to be viable, and how those relate to a local object returned from a function being treated as an rvalue such that it may be moved. – juanchopanza Jun 30 '18 at 20:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/174094/discussion-between-nathan-and-juanchopanza). – Nathan Jun 30 '18 at 20:34
  • @juanchopanza What are the missing conditions for NRVO to be viable in the example showed in this answer? The OP also tagged their question as C++17. – Bob__ Jun 30 '18 at 20:40
2

Any object created on the free store with new has to be cleaned up by delete. Otherwise, you'll have a memory leak as once your method returns the memory isn't deallocated.

Anatolii
  • 11,658
  • 3
  • 27
  • 51