8

Coming from a Java background, I'm still a little confused about allocating memory in C++. I'm pretty sure the first two statements are correct:

void method() {
    Foo foo;    // allocates foo on the stack, and the memory is freed
                // when the method exits
}

void method2() {
    Foo *foo = new Foo();   // allocates foo on the heap
    delete foo;             // frees the memory used by foo
}

But what about something like this?

void method3() {
    Foo foo = *new Foo();   // allocates foo on the heap, and then copies it to the stack?
                            // when the method exits, the stack memory is freed, but the heap memory isn't?
}

Say I added foo to a global array inside method3(). If I tried to access one of foo's data members after the method exits, would that work? And is method3() prone to memory leaks?

Thanks in advance.

trincot
  • 317,000
  • 35
  • 244
  • 286
nebulabrot
  • 465
  • 1
  • 6
  • 13

1 Answers1

10
Foo foo(); 

Declares a function by the name foo which returns a Foo object and does not take any arguments. It is known as the most vexing parse in C++. You probably meant:

Foo foo; 

It creates a foo object locally/automatic storage. The object is automatically deallocated once the scope { } in which it is declared ends.


Foo *foo = new Foo();   // allocates foo on the heap
delete foo;

This is true, the object on freestore pointed by foo is deallocated once you call delete. There is no memory leak.


 Foo foo = *new Foo(); 

Allocates a Foo object on freestore and then a copy of that object is used to initialize foo. Since you do not have a pointer to the freestore allocated object, it causes a memory leak. Note that if the destructor of Foo has some code which causes side effects then it is not merely memory leak but undefined behavior.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • I meant `Foo foo()` to call the no argument constructor for class `Foo`. But you're right, I'll change it in the question to avoid confusion. – nebulabrot Feb 24 '13 at 07:20
  • 1
    @nebulabrot: `Foo foo;` does that, not `Foo foo();` – Alok Save Feb 24 '13 at 07:21
  • Why undefined behavior if side effects are present in Foo destructor? I can think of a couple of examples with complex `Foo` where it would work just fine, even without memory leak! – CygnusX1 Feb 24 '13 at 07:26
  • @CygnusX1: Because the C++ standard says so. – Alok Save Feb 24 '13 at 07:29
  • 1
    @Alok Save: Saying that "standard says so" is most unhelpful answer. Which line of the standard says so? Are you sure that for every definition of `Foo` you will hit that standard issue? – CygnusX1 Feb 24 '13 at 07:32
  • 1
    I answered it myself by visiting: http://stackoverflow.com/questions/9920973/new-without-delete-is-undefined-behavior-or-merely-memory-leak – CygnusX1 Feb 24 '13 at 07:37
  • @CygnusX1: *"You can think of a number of scenarios*" is not a compelling reason for me to prove anything to you. And If you put in that effort of doing that search before, You would have saved yourself the talk and me this comment. – Alok Save Feb 24 '13 at 07:38
  • 1
    I could completely omit the "number of scenarios" statement and still ask a perfectly valid question about which element of the standard leads to the undefined behavour. Sadly you were not compelled to answer it, but I found it myself :) As for concrete scenario example: above code will be completely fine if the constructor of Foo has a side effect of registering itself in some global set of created objects (and destructor - deregistering). That sort of simple management would prevent any memory leak of Foo in the above examples. Another example could include overloaded new operator for Foo... – CygnusX1 Feb 24 '13 at 17:00
  • @AlokSave: thanks sir. Is there any way to prevent memory leak when i write like Foo f=*new Foo(); ? – Destructor Mar 20 '15 at 11:12
  • @meet: No, because to deallocate the memory you need the starting address of that memory block. You call `delete` on a pointer which points to that memory block but once you execute this statement you lose that starting address. – Alok Save Mar 21 '15 at 05:34
  • @AlokSave Does `Foo &foo = *new Foo();` have memory leak? – Rix Apr 29 '15 at 05:50
  • @Rix: Yes, because you lose the address which is pointing to the dynamic memory. – Alok Save Apr 29 '15 at 10:49