0

I'm new in C++, and i want to know how memory released in this case: I have a function:

void myFunction() {
    Foo foo; // at this line, new Foo instance created with constructor Foo(), instance1
    foo = new Foo(params); // this line, reassign object, new another instance created - instance2
}

When the program pass this function, instance1 is released automatically or not? The same question with instance2?

Fahim Al Mahmud Ashik
  • 1,083
  • 10
  • 26
Viet Dung
  • 29
  • 3
  • 1
    Being new to C++ I would like to let you know that it is a different language to C. Please use only the relevant language tag. – kaylum Jan 31 '17 at 04:02
  • 3
    This wouldn't compile, you're trying to assign a `Foo *` to a `Foo` which is a type mismatch. – greatwolf Jan 31 '17 at 04:03
  • Foo foo; << this line neither create any instance nor call the constructor Foo()..it's just a reference variable for Foo type object.However foo=new Foo(params); this line creates an instance of Foo class. – Fahim Al Mahmud Ashik Jan 31 '17 at 04:04
  • @kaylum i think using class Foo that i'm using C++ – Viet Dung Jan 31 '17 at 04:05
  • @VietDung Of course. That's why you shouldn't tag your question with `C`. – kaylum Jan 31 '17 at 04:09
  • @ash12 Yes, it does create a Foo. It uses the default constructor. This isn't Java or C# where a variable is initialized to null. – Nic Jan 31 '17 at 05:10

1 Answers1

3

The short answer is this wouldn't compile. You're attempting to assign a Foo * to Foo. eg. on gcc this generates the compile error:

In function 'void myFunction()':
error: no match for 'operator=' (operand types are 'Foo' and 'Foo*')

But let's just pretend for arguments sake this isn't an issue. What would happen above is foo gets default constructed on the local stack of myFunction. On exit, foo goes out of scope and its destructor is executed so no leak here.

Now new Foo(params);, on the other hand, is a different story. This allocates space on the free store for a Foo instance and calls the Foo(params) constructor. When myFunction exits, the pointer to this dynamically allocated Foo will still exist(even if you can't refer to it) since there's no delete operator paired with it. Unless you delete this pointer elsewhere in your code this will leak.

greatwolf
  • 20,287
  • 13
  • 71
  • 105
  • OK thanks. Then i think code will work: void myFunction() { Foo* foo; delete foo; foo = new Foo(params); delete foo; } – Viet Dung Jan 31 '17 at 04:19
  • 5
    @VietDung no, you really should be using `std::unique_ptr` and `std::make_unique` for this. Manually invoking `new` is generally considered code smell for modern C++11 code. – greatwolf Jan 31 '17 at 04:22
  • 3
    That updated code may compile, but `delete` is wrong because it's releasing an unallocated pointer. When you declare an instance of a variable (and not a pointer), space is allocated on the stack for you, and it gets constructed. When it goes out of scope, it's destroyed and freed. When you declare a pointer in C++, space is allocated *for the pointer*—but not the object. `new` allocates and constructs the object on the free store, and you can put the reference in your pointer. Now, when done with it, you can `delete` it. But free store allocation is expensive, so avoid it if you can. – Perette Jan 31 '17 at 04:28
  • @greatwolf but i don't want using -std=c++11. – Viet Dung Jan 31 '17 at 04:40
  • @Perette Barella then that code will delete all instance when out of function? void myFunction() { Foo* foo = new Foo(); delete foo; foo = new Foo(params); delete foo; } – Viet Dung Jan 31 '17 at 04:40
  • 2
    If you're doing C++ you want to be doing C++11 if not C++14 unless you have a very, very compelling reason to avoid it. – tadman Jan 31 '17 at 05:00
  • Yes, that last snippet will balance the new and delete. But, unless you need to return the object, it's simpler to avoid new/delete: void myfunction() { { Foo foo; } { Foo foo (params); }}. The first is constructed on the stack, then goes out of scope and is destroyed. Then the second is constructed in its scope, then goes out of scope and is destroyed. I'm getting the sense you're coming out of something like Java or JavaScript where all objects are references. In C++, this isn't true. See [this explanation](http://stackoverflow.com/questions/333443/c-object-instantiation) for more. – Perette Jan 31 '17 at 16:36