1
#include <iostream>
using namespace std;

int *arrExpand(int *arr, int arrSize)
{
    int *p = new int [arrSize * 2];
    for(int i =0; i < arrSize * 2; i++)
    {   if(i < arrSize)
            p[i] = arr[i];
        if(i > arrSize)
            p[i] = 0;
    }
    return p;
}

int main()
{
    int mySize = 5;
    int myArr[5] = {1,2,3,4,5};

    cout << "Array: ";
    for(auto v: myArr)
        cout << v;
    for( int i = 0; i < mySize * 2; i++)
        cout  << endl << *(arrExpand(myArr,mySize)+i);
    //return is not assigned == delete not needed?
    return 0;
}

Does the function delete and deallocate the memory since the return is not assigned? Does the memory need to be deallocated?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
tariqebadi
  • 15
  • 1
  • 3

2 Answers2

4

As already mentioned, you do indeed need to delete[] the memory. You can just remember this simple rule:

delete everything you newed exactly once. The same applies to delete[] and new[].

I do however not agree with the smart-pointer advice. While std::unique_ptr would have some advantages as drop-in replacement for raw arrays in large, old codebases (as described here), the much more natural alternative is std::vector:

std::vector<int> arrExpand(int *arr, int arrSize)
{
    std::vector<int> p (arrSize * 2);
    for(int i =0; i < arrSize * 2; i++)
    {   if(i < arrSize)
            p[i] = arr[i];
        if(i > arrSize)
            p[i] = 0;
    }
    return p;
}

or even better

std::vector<int> arrExpand(const std::vector<int> &arr)
{
    std::vector<int> p (arr.size() * 2);
    for(int i =0; i < arr.size() * 2; i++)
    {   if(i < arr.size())
            p[i] = arr[i];
        if(i > arr.size())
            p[i] = 0;
    }
    return p;
}

It is generally (at least I do not know a counter-example) a very good idea to use std::vector as your standard runtime-sized array. One good reason is the automatic and correct memory management. It also comes with quite a few useful member functions, including knowing its own size.

Community
  • 1
  • 1
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
1

Short answer: Yes, it needs to be deleted.

If you allocate objects with new, you should also delete them. Using plain pointers is error-prone and a lot of manual work, this is why C++ has several smart pointers available, most importantly std::unique_ptr and std::shared_ptr. In your case std::unique_ptr might be an option.

Example:

std::unique_ptr<int[]> arrExpand(int *arr, int arrSize)
{
    std::unique_ptr<int[]> p( new int [arrSize * 2] );
    for(int i =0; i < arrSize * 2; i++)
    {   if(i < arrSize)
            p[i] = arr[i];
        if(i > arrSize)
            p[i] = 0;
    }
    return std::move(p);
}

Which can be used in your example like this:

auto result = arrExpand(myArr,mySize);
for( int i = 0; i < mySize * 2; i++)
    cout  << endl << result[i];

Note that you should store the result of arrExpand once before the loop, otherwise the function will be called for each iteration of the loop which is quite inefficient.

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • Where would I place the delete if its not assigned? before the return 0? – tariqebadi May 10 '15 at 21:25
  • @tariqebadi That's the reason to use smart pointers: You don't have to call `delete`, they will take care of it. When you use a `std::unique_ptr` like I showed, you are mostly safe and there will be no resource leaks - even in case of exceptions. – Daniel Frey May 10 '15 at 21:28