-3

Possible Duplicate:
Why does the use of ‘new’ cause memory leaks?

I've encountered a small problem like this

int main() {
    int i = *new int;
    delete &i;
    return 0;
}

It compiles ok, but when executing, the shell gives the following :

a.out(38303) malloc: *** error for object 0x7fff5fbff8cc: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap

while

int main() {
    int *i = new int;
    delete i;
    return 0;
}

runs normally as expected.

What bothers me is that, doesn't the first case use the "new" operator to allocate memory? Why does it cause error when delete it?

I've searched on web for several times, but I cannot find a proper explanation. Can anyone tell me why is it wrong? thanks :)

Community
  • 1
  • 1
Marco
  • 1
  • 1

5 Answers5

11

The problem is that you have a memory leak and you are deleting something that wasn't dynamically allocated. Why? Because you dynamically allocate an int then you copy its value into i. You then attempt to delete the object i through a pointer to it, but i wasn't dynamically allocated - its value was just initialized from something that was. You've lost any pointer to the object you actually dynamically allocated.

Diagrammatically, first you new int, creating an int object with dynamic storage duration and returning a pointer to that int:

        _____        ______
Heap:  | int | <--- | int* |
       |_____|      |______|

You then dereference the pointer, giving you the int object and copy its value to an int object with automatic storage duration. After this, the pointer you got from new is lost because you didn't store it anywhere.

        _____
Heap:  | int |
       |_____|
        _____
Stack: | int |
       |_____|

Then you take the address of the int with automatic storage duration and attempt to delete it.

        _____
Heap:  | int |
       |_____|
        _____        ______
Stack: | int | <--- | int* | <-- Cannot delete because it was
       |_____|      |______|     not dynamically allocated
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
10

What you probably wanted to write was this:

int main() {
    int& i = *new int;   // note the reference type
    delete &i;
    return 0;
}

But be aware that nobody in their right mind would hire you if he saw that code.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • Though that works. I don't think this is something we want people to do. The semantics for the reader are all wrong. – Martin York Dec 21 '12 at 17:37
3

delete &i fails because you're attempting to delete a pointer that wasn't returned by new. This is undefined behaviour.

In

int i = *new int;

you're assigning the value of the newly allocated int to i. The pointer is getting lost.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
3

doesn't the first case use the "new" operator to allocate memory?

It does indeed. But you don't keep hold of a pointer to it. Instead, you copy its (uninitialised) value into a local variable, and leak the allocated memory; you have lost the only pointer to the memory, so there is no way to delete it.

Why does it cause error when delete it?

Because &i points to the local variable i, not the allocated memory. It's an error to delete anything that wasn't allocated with new, including local variables.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1
int main() {
    int i = *new int;
    delete &i;
   return 0;
}

Your first line only sets the value of i. It still lives on the stack, making it illegal to pass its address to delete.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278