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
  • 63,072
  • 85
  • 231
  • 359
  • 8
    It is necessary. Use vectors instead. And forget about evil C arrays. – Ron Jun 30 '18 at 20:02
  • 8
    Yes, this is hard to maintain. That's why people haven't been using C++ like this for nearly a decade now. – Kerrek SB Jun 30 '18 at 20:03
  • Allocation → free/delete – Déjà vu Jun 30 '18 at 20:03
  • You allocate it with `new` then you *own* and are responsible for releasing it unless you can give that responsibility to some other part of your code, in which case that code must release it. – tadman Jun 30 '18 at 20:05
  • Relevant read: https://stackoverflow.com/a/655206 , Numerous links to further reading: https://stackoverflow.com/a/716360 – user2864740 Jun 30 '18 at 20:06

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,777
  • 1
  • 28
  • 35
  • 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
  • 14,139
  • 4
  • 35
  • 65