Home > Software engineering >  Why does delete[] work in one case but not another?
Why does delete[] work in one case but not another?

Time:03-11

Could someone explain to me how delete[] works in the function below?

Specifically, arr = arrtemp; delete[] arrtemp; fails, but delete[] arr; arr = arrtemp works.

void AddElement(int *&arr, int &n, int pos, int val){
    int *arrtemp = new int[n   1];
    
    for(int i = 0; i <= pos; i  ){
        *(arrtemp   i) = *(arr   i);
    }
    for(int i = pos; i < n; i  ){
        *(arrtemp   i   1) = *(arr   i);
    }
    *(arrtemp   pos) = val;
    n  ;
    
    //This works just fine
    delete[] arr;
    arr = arrtemp;

    //But this one fails
    //arr = arrtemp;
    // delete[] arrtemp;
}

My thought was that I assign arr = arrtemp so that pointer arr now points to the added array, and I delete[] arrtemp should have no effect on arr, but it does @@ and I don't know why.

CodePudding user response:

Working scenario

  • arr - has address 'A' which it got from caller
  • arrtemp - has address 'B'
    delete[] arr;   // deleted 'A'
    arr = arrtemp;  // assigned addr 'B' to arr;  
  • arr caller has still valid but address of arrtemp. Hence it is working

In wrong scenario

  • arr - has address 'A' which it got from caller
  • arrtemp - has address 'B'
     arr = arrtemp;  // arr has address 'B'
     delete[] arrtemp; // deleted 'B' 

so address on arr is deleted. Assign just the value to arr from arrtemp and not address.

CodePudding user response:

arr = arrtemp; assigns one pointer to another. Nothing is copied. delete[] arrtemp deletes the memory pointed to by arrtemp. Since arr and arrtemp point to the same place, the memory that both pointers point to has been freed and is no longer usable.

CodePudding user response:

My thought was that I assign arr = arrtemp so that pointer arr now points to the added array, and I delete[] arrtemp should have no effect on arr,

Strictly speaking, this much is true. However, if you take this viewpoint, then strictly speaking, delete[] arrtemp should have no effect on arrtemp. Deleting the memory to which arrtemp points does not change arrtemp; it still points to the same memory location. What has changed is that accessing that memory is no longer valid.

but it does

Strictly speaking, this is false. Deleting the memory to which arrtemp points has no effect on arr. And that likely accounts for the symptoms you are seeing. There is no effect on arr, so arr still points to the same memory as before the deletion, to the same memory to which arrtemp points, to the memory that is no longer valid to access because it has been deleted.

Before the deletion:

-----------
| arr     |---\
-----------   |
              |    --------------------
 same address |--->| allocated memory | valid to access
              |    --------------------
-----------   |
| arrtemp |---/
-----------

After the deletion:

-----------
| arr     |---\
-----------   |
              |     ~~~~~~~~~~~~~~~~~~~~
 same address |--->(  deleted memory    ) invalid to access
              |     ~~~~~~~~~~~~~~~~~~~~
-----------   |
| arrtemp |---/
-----------

There is no change to arr (the pointer), but there is a change to *arr (the pointed-to object). This distinction is important. When arr == arrtemp, then deleting *arrtemp also deletes *arr. The situation is not merely that *arr is equivalent to *arrtemp, but that *arr is *arrtemp. Two names for the same object. Calling delete[] arrtemp directs the computer to delete the array (starting at) *arrtemp, a.k.a. *arr in your situation. Accessing that array after the deletion is invalid, regardless of which name you use to access the array.

  • Related