How to delete[] decayed array?

113 Views Asked by At

How to delete an array declared with new if I don't have access to the original pointer x? Let's assume, I know the array size.

For example, if I write the following code:

void enlarge(int * x) {
    int * tmp = new int[20];
    memcpy(tmp, x, 10*sizeof(int));
    delete[] x; //?
    x = tmp;
}

int main() {
    int * x = new int[10];
    enlarge(x);
    delete[] x; //??? free(): double free detected in tcache 2
}
  1. Would delete[] within enlarge() function know how much memory to free?
  2. Apparently, delete[] within main() results in an error during execution. Why? How to avoid it?
3

There are 3 best solutions below

0
Vlad from Moscow On BEST ANSWER

The function enlarge produces a memory leak because the pointer x declared in main is passed to the function by value. That is the function deals with a copy of the value of the original pointer x. Changing within the function the copy leaves the original pointer x declared in main unchanged.

As a result this statement in main

delete[] x;

invokes undefined behavior because the memory pointed to by the pointer x was already freed in the function enlarge.

You need to pass the pointer by reference like

void enlarge(int * &x) {
    int * tmp = new int[20];
    memcpy(tmp, x, 10*sizeof(int));
    delete[] x;
    x = tmp;
}

Pay attention to that instead of raw pointers it is better to use standard container std::vector.

0
fireshadow52 On

The delete call within enlarge is deleting the int *x declared in main, as you're simply passing the pointer to a new function. This is why delete[] x in main gives you a double free; that pointer doesn't exist anymore.

Update: I should clarify that when you pass a pointer by value, you're effectively copying it. deleteing a copy of a pointer also deletes the original pointer.

1
eerorika On

How to delete an array declared with new if I don't have access to the original pointer x?

You cannot. In order to delete a dynamic array, you must know the pointer to the first element of that array - i.e. the pointer that was returned by new.

Would delete[] within enlarge() function know how much memory to free?

Yes.

Apparently, delete[] within main() results in an error during execution. Why?

Because the same pointer was already deleted in enlarge. If you delete a pointer more than once, the behaviour of the program is undefined.

How to avoid it?

Don't delete a pointer more than once.

P.S. enlarge leaks the array that it allocates. Don't use new and delete. Use RAII containers such as std::vector instead.


Ah, so array decay affects only statically declared arrays

Array decay is an implicit conversion of an expression of array type to a pointer to first element. The type of x is int*. That is not an array type. int* is a pointer type. As it isn't an array type, it doesn't implicitly convert to a pointer to first element. x is already the pointer to the first element.