Removing objects from memory in c++ - c++

I am new to c++ but from what I understood you need to delete objects from memory when you are done with them.
Having a class called myClass. If I create a new instance and call some of its functionalities. Like so:
MyClass p;
p.funcCall(12);
p.anOtherFuncCall(4);
How am I supposed to free the memory occupied by p again? I read this Microsoft article. But if I change it to:
MyClass* p = new MyClass
... call fucntions
delete p;
I can no longer call my functions like p.funcCall(12).
If I understood memory management in c++ incorrectly I would love to hear that as well.

In this code
MyClass p;
p.funcCall(12);
p.anOtherFuncCall(4);
You don't have to manually delete p. It is automatically invalidated once it goes out of scope. This is explained in greater detail here. You can just leave it this way.
MyClass* p = new MyClass
... call fucntions
delete p;
You can also do it that way if you want. Since p is not a MyClass anymore but a pointer to one, the syntax is different, though. You have to write it like this instead:
p->funcCall(12);

So basically C++ won't manage memory for you, at least it's not a default feature of the language. That certainly doesn't mean that you need to store every object as a pointer and free it manually though. In your case the object is initialized in the local scope which means it will get destroyed as soon as it leaves that scope. This is because you constructed it as a value, if you had allocated memory yourself for it (i.e global scope) then you're responsible for freeing said memory. There's another option for pointers as well though, using smart pointers will automate the cleanup of objects in the global scope.

Related

Is destroying then constructing at this inside member function defined behavior? [duplicate]

I want to reset an object. Can I do it in the following way?
anObject->~AnObject();
anObject = new(anObject) AnObject();
// edit: this is not allowed: anObject->AnObject();
This code is obviously a subset of typical life cycle of an object allocated by in placement new:
AnObject* anObject = malloc(sizeof(AnObject));
anObject = new (anObject) AnObject(); // My step 2.
// ...
anObject->~AnObject(); // My step 1.
free(anObject)
// EDIT: The fact I used malloc instead of new doesn't carry any meaning
The only thing that's changed is the order of constructor and destructor calls.
So, why in the following FAQ
all the threatening appear?
[11.9] But can I explicitly call a
destructor if I've allocated my object
with new?
FAQ: You can't, unless the object was
allocated with placement new. Objects
created by new must be deleted, which
does two things (remember them): calls
the destructor, then frees the memory.
FQA: Translation: delete is a way to
explictly call a destructor, but it
also deallocates the memory. You can
also call a destructor without
deallocating the memory. It's ugly and
useless in most cases, but you can do
that.
The destructor/constructor call is obviously normal C++ code. Guarantees used in the code directly result from the in placement new guarantees. It is the core of the standard, it's rock solid thing. How can it be called "dirty" and be presented as something unreliable?
Do you think it's possible, that the in-placement and non-in-placement implementation of new are different? I'm thinking about some sick possibility, that the regular new can for example put size of the memory block allocated before the block, which in-placement new obviously would not do (because it doesn't allocate any memory). This could result in a gap for some problems... Is such new() implementation possible?
Don't get sucked in by the FQA troll. As usual he gets the facts wrong.
You can certainly call the destructor directly, for all objects whether they are created with placement new or not. Ugly is in the eye of the beholder, it is indeed rarely needed, but the only hard fact is that both memory allocation and object creation must be balanced.
"Regular" new/delete simplifies this a bit by tying memory allocation and object creation together, and stack allocation simplifies it even further by doing both for you.
However, the following is perfectly legal:
int foo() {
CBar bar;
(&bar)->~CBar();
new (&bar) CBar(42);
}
Both objects are destroyed, and the stack memory is automatically recycled too. yet unlike the FQA claims, the first call of the destructor is not preceded by placement new.
Why not implement a Clear() method, that does whatever the code in the body of the destructor does? The destructor then just calls Clear() and you call Clear() directly on an object to "reset it".
Another option, assuming your class supports assignment correctly:
MyClass a;
...
a = MyClass();
I use this pattern for resetting std::stack instances, as the stack adaptor does
not provide a clear function.
Technically it is bad practice to call constructors or destructors explicitly.
The delete keyword ends up calling them when you use it. Same goes for new with constructors.
I'm sorry but that code makes me want to tear my hair out. You should be doing it like this:
Allocate a new instance of an object
AnObject* anObject = new AnObject();
Delete an instance of an object
delete anObject;
NEVER do this:
anObject->~AnObject(); // My step 1.
free(anObject)
If you must "reset" an object, either create a method which clears all the instance variables inside, or what I would recommend you do is Delete the object and allocate yourself a new one.
"It is the core of the language?"
That means nothing. Perl has about six ways to write a for loop. Just because you CAN do things in a language because they are supported does mean you should use them. Heck I could write all my code using for switch statements because the "Core" of the language supports them. Doesn't make it a good idea.
Why are you using malloc when you clearly don't have to. Malloc is a C method.
New and Delete are your friends in C++
"Resetting" an Object
myObject.Reset();
There you go. This way saves you from needlessly allocating and deallocating memory in a dangerous fashion. Write your Reset() method to clear the value of all objects inside your class.
You cannot call the constructor in the manner indicated by you. Instead, you can do so using placement-new (like your code also indicates):
new (anObject) AnObject();
This code is guaranteed to be well-defined if the memory location is still available – as it should be in your case.
(I've deleted the part about whether this is debatable code or not – it's well-defined. Full stop.)
By the way, Brock is right: how the implementation of delete isn't fixed – it is not the same as calling the destructor, followed by free. Always pair calls of new and delete, never mix one with the other: that's undefined.
Yes, what you are doing is valid most of the time. [basic.life]p8 says:
If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:
the storage for the new object exactly overlays the storage location which the original object occupied, and
the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and
the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and
neither the original object nor the new object is a potentially-overlapping subobject ([intro.object]).
So it is legal if you don't have a const or reference member.
If you don't have this guarantee, you need to use std::launder or use the pointer returned by placement new (like you're doing anyways) if you want to use the new object:
// no const/ref members
anObject->~AnObject(); // destroy object
new (anObject) AnObject(); // create new object in same storage, ok
anObject->f(); // ok
// const/ref members
anObject->~AnObject();
auto newObject = new (anObject) AnObject();
anObject->f(); // UB
newObject->f(); // ok
std::launder(anObject)->f(); // ok
Note that they're not malloc and free that are used, but operator new and operator delete. Also, unlike your code, by using new you're guaranteeing exception safety. The nearly equivalent code would be the following.
AnObject* anObject = ::operator new(sizeof(AnObject));
try
{
anObject = new (anObject) AnObject();
}
catch (...)
{
::operator delete(anObject);
throw;
}
anObject->~AnObject();
::operator delete(anObject)
The reset you're proposing is valid, but not idiomatic. It's difficult to get right and as such is generally frowned upon and discouraged.
Why not reset using the operator=()? This is not debatable and by far more readable.
A a;
//do something that changes the state of a
a = A(); // reset the thing
You can't call the constructor like that, but there's nothing wrong with reusing the memory and calling placement new, as long you don't delete or free (deallocate) the memory. I must say reseting an object like this is a little sketchy. I would write an object to be explicitly resetable, or write a swap method and use that to reset it.
E.g.
anObject.swap( AnObject() ); // swap with "clean" object
If your object has sensible assignment semantics (and correct operator=), then *anObject = AnObject() makes more sense, and is easier to understand.
It is far better just to add something like a Reset() method to your object rather than play with placement new's.
You are exploiting the placement new feature which is intended to allow you to control where an object is allocated. This is typically only an issue if your hardware has "special" memory like a flash chip. IF you want to put some objects in the flash chip, you can use this technique. The reason that it allows you to explicitly call the destructor is that YOU are now in control of the memory, so the C++ compiler doesn't know how to do the deallocation part of the delete.
It is not saving you much code either, with a reset method, you will have to set the members to their starting values. malloc() doesn't do that so you are going to have to write that code in the constructor anyway. Just make a function that sets your members to the starting values, call it Reset() call it from the constructor and also from anywhere else you need.

C++ placement new for local objects [duplicate]

I want to reset an object. Can I do it in the following way?
anObject->~AnObject();
anObject = new(anObject) AnObject();
// edit: this is not allowed: anObject->AnObject();
This code is obviously a subset of typical life cycle of an object allocated by in placement new:
AnObject* anObject = malloc(sizeof(AnObject));
anObject = new (anObject) AnObject(); // My step 2.
// ...
anObject->~AnObject(); // My step 1.
free(anObject)
// EDIT: The fact I used malloc instead of new doesn't carry any meaning
The only thing that's changed is the order of constructor and destructor calls.
So, why in the following FAQ
all the threatening appear?
[11.9] But can I explicitly call a
destructor if I've allocated my object
with new?
FAQ: You can't, unless the object was
allocated with placement new. Objects
created by new must be deleted, which
does two things (remember them): calls
the destructor, then frees the memory.
FQA: Translation: delete is a way to
explictly call a destructor, but it
also deallocates the memory. You can
also call a destructor without
deallocating the memory. It's ugly and
useless in most cases, but you can do
that.
The destructor/constructor call is obviously normal C++ code. Guarantees used in the code directly result from the in placement new guarantees. It is the core of the standard, it's rock solid thing. How can it be called "dirty" and be presented as something unreliable?
Do you think it's possible, that the in-placement and non-in-placement implementation of new are different? I'm thinking about some sick possibility, that the regular new can for example put size of the memory block allocated before the block, which in-placement new obviously would not do (because it doesn't allocate any memory). This could result in a gap for some problems... Is such new() implementation possible?
Don't get sucked in by the FQA troll. As usual he gets the facts wrong.
You can certainly call the destructor directly, for all objects whether they are created with placement new or not. Ugly is in the eye of the beholder, it is indeed rarely needed, but the only hard fact is that both memory allocation and object creation must be balanced.
"Regular" new/delete simplifies this a bit by tying memory allocation and object creation together, and stack allocation simplifies it even further by doing both for you.
However, the following is perfectly legal:
int foo() {
CBar bar;
(&bar)->~CBar();
new (&bar) CBar(42);
}
Both objects are destroyed, and the stack memory is automatically recycled too. yet unlike the FQA claims, the first call of the destructor is not preceded by placement new.
Why not implement a Clear() method, that does whatever the code in the body of the destructor does? The destructor then just calls Clear() and you call Clear() directly on an object to "reset it".
Another option, assuming your class supports assignment correctly:
MyClass a;
...
a = MyClass();
I use this pattern for resetting std::stack instances, as the stack adaptor does
not provide a clear function.
Technically it is bad practice to call constructors or destructors explicitly.
The delete keyword ends up calling them when you use it. Same goes for new with constructors.
I'm sorry but that code makes me want to tear my hair out. You should be doing it like this:
Allocate a new instance of an object
AnObject* anObject = new AnObject();
Delete an instance of an object
delete anObject;
NEVER do this:
anObject->~AnObject(); // My step 1.
free(anObject)
If you must "reset" an object, either create a method which clears all the instance variables inside, or what I would recommend you do is Delete the object and allocate yourself a new one.
"It is the core of the language?"
That means nothing. Perl has about six ways to write a for loop. Just because you CAN do things in a language because they are supported does mean you should use them. Heck I could write all my code using for switch statements because the "Core" of the language supports them. Doesn't make it a good idea.
Why are you using malloc when you clearly don't have to. Malloc is a C method.
New and Delete are your friends in C++
"Resetting" an Object
myObject.Reset();
There you go. This way saves you from needlessly allocating and deallocating memory in a dangerous fashion. Write your Reset() method to clear the value of all objects inside your class.
You cannot call the constructor in the manner indicated by you. Instead, you can do so using placement-new (like your code also indicates):
new (anObject) AnObject();
This code is guaranteed to be well-defined if the memory location is still available – as it should be in your case.
(I've deleted the part about whether this is debatable code or not – it's well-defined. Full stop.)
By the way, Brock is right: how the implementation of delete isn't fixed – it is not the same as calling the destructor, followed by free. Always pair calls of new and delete, never mix one with the other: that's undefined.
Yes, what you are doing is valid most of the time. [basic.life]p8 says:
If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:
the storage for the new object exactly overlays the storage location which the original object occupied, and
the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and
the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and
neither the original object nor the new object is a potentially-overlapping subobject ([intro.object]).
So it is legal if you don't have a const or reference member.
If you don't have this guarantee, you need to use std::launder or use the pointer returned by placement new (like you're doing anyways) if you want to use the new object:
// no const/ref members
anObject->~AnObject(); // destroy object
new (anObject) AnObject(); // create new object in same storage, ok
anObject->f(); // ok
// const/ref members
anObject->~AnObject();
auto newObject = new (anObject) AnObject();
anObject->f(); // UB
newObject->f(); // ok
std::launder(anObject)->f(); // ok
Note that they're not malloc and free that are used, but operator new and operator delete. Also, unlike your code, by using new you're guaranteeing exception safety. The nearly equivalent code would be the following.
AnObject* anObject = ::operator new(sizeof(AnObject));
try
{
anObject = new (anObject) AnObject();
}
catch (...)
{
::operator delete(anObject);
throw;
}
anObject->~AnObject();
::operator delete(anObject)
The reset you're proposing is valid, but not idiomatic. It's difficult to get right and as such is generally frowned upon and discouraged.
Why not reset using the operator=()? This is not debatable and by far more readable.
A a;
//do something that changes the state of a
a = A(); // reset the thing
You can't call the constructor like that, but there's nothing wrong with reusing the memory and calling placement new, as long you don't delete or free (deallocate) the memory. I must say reseting an object like this is a little sketchy. I would write an object to be explicitly resetable, or write a swap method and use that to reset it.
E.g.
anObject.swap( AnObject() ); // swap with "clean" object
If your object has sensible assignment semantics (and correct operator=), then *anObject = AnObject() makes more sense, and is easier to understand.
It is far better just to add something like a Reset() method to your object rather than play with placement new's.
You are exploiting the placement new feature which is intended to allow you to control where an object is allocated. This is typically only an issue if your hardware has "special" memory like a flash chip. IF you want to put some objects in the flash chip, you can use this technique. The reason that it allows you to explicitly call the destructor is that YOU are now in control of the memory, so the C++ compiler doesn't know how to do the deallocation part of the delete.
It is not saving you much code either, with a reset method, you will have to set the members to their starting values. malloc() doesn't do that so you are going to have to write that code in the constructor anyway. Just make a function that sets your members to the starting values, call it Reset() call it from the constructor and also from anywhere else you need.

Will "new" cause memory leak in function as well?

Assume we want to declare a function in C++, in which I declare a local variable int p=new int [10]; and I do some operations afterwards and in the end I return p; .
As is often said, if we use new , we must delete. But I think in this case, we should NOT delete, right? Otherwise, it can't return p at all, right? However, I am also thinking if we should delete the item the function returns when we test it in int main().
The rule is that for every new there must be a delete (and for every new[] a delete[] *), but it need not be in the same scope. It is common to have functions dynamically create an object and transfer ownership of that object to the caller. The caller will then be responsible for deleting the memory.
That being said, you should avoid directly calling new and delete in your code, and prefer using other constructs that are safe (take care of the memory automatically for you). In the particular case you mention, a std::vector<int> initialized with 10 elements will have little overhead over the pointer and will ensure that the memory is released whenever the object is destroyed.
* Depending on your implementation, there might be cases where you new (or new[]) and not delete, if the memory is handed to a smart pointer. For example in C++11 you could do:
std::unique_ptr<int[]> f() {
std::unique_ptr<int[]> p(new int[10]); // new is unmatched
// ...
return p;
}
This is fine, as handling the pointer to the std::unique_ptr ensures that it will call delete[] internally when it goes out of scope (if not moved to a different smart pointer).
The caller would need to know you returned something created with new [], and call delete [] when necessary. There is a lot of scope for error in such a construct. Better return something that takes care of its own memory, such as an std::vector or an std::unique_ptr.
delete should be done when the program is done using the array. It doesn't have to be in the same function.
If delete always needed to be done when the function ends, it would get added automatically (unique_ptr is a way to tell C++11 to automatically free something new when the function ends)
They are allocated from heap. So you can and should delete on anywhere outside the function.
New and Delete does not use stack. Same for malloc and free.
You can delete [] p in the new scope it is returned after you are done with it. However, it is not a good practice to just allocate a memory with new and giving the ownership to another scope. You can utilize std::vector or smart pointers.

New Object variations

This is a very newbie question, but something completely new to me. In my code, and everywhere I have seen it before, new objects are created as such...
MyClass x = new MyClass(factory);
However, I just saw some example code that looks like this...
MyClass x(factory);
Does that do the same thing?
Not at all.
The first example uses dynamic memory allocation, i.e., you are allocating an instance of MyClass on the heap (as opposed to the stack). You would need to call delete on that pointer manually or you end up with a memory leak. Also, operator new returns a pointer, not the object itself, so your code would not compile. It needs to change to:
MyClass* x = new MyClass(factory);
The second example allocated an instance of MyClass on the stack. This is very useful for short lived objects as they will automatically be cleaned up when the leave the current scope (and it is fast; cleaning up the stack involves nothing more than incrementing or decrementing a pointer).
This is also how you would implement the Resource Acquisition is Initialization pattern, more commonly referred to as RAII. The destructor for your type would clean up any dynamically allocated memory, so when the stack allocated variable goes out of scope any dynamically allocated memory is cleaned up for you without the need for any outside calls to delete.
No. When you use new, you create objects off the heap that you must then delete later. In addition, you really need MyClass*. The other form creates an object on the stack that will be automatically destroyed at end of scope.

NULL pointer is the same as deallocating it?

I was working on a piece of code and I was attacked by a doubt: What happens to the memory allocated to a pointer if I assign NULL to that pointer?
For instance:
A = new MyClass();
{...do something in the meantime...}
A = NULL;
The space is still allocated, but there is no reference to it. Will that space be freed later on, will it be reused, will it remain on stack, or what?
This is a classic leak.
As you say, the memory remains allocated but nothing is referencing it, so it can never be reclaimed - until the process exits.
The memory should be deallocated with delete - but using a smart pointer (e.g. std::auto_ptr or boost::shared_ptr (or tr1::shared_ptr) to wrap the pointer is a much safer way of working with pointers.
Here's how you might rewrite your example using std::auto_ptr:
std::auto_ptr a( new MyClass() );
/*...do something in the meantime...*/
a.reset();
(Instead of the call to reset() you could just let the auto_ptr instance go out of scope)
Under most circumstances, that will cause a memory leak in your process. You have several options for managing memory in C++.
Use a delete to manually free memory when you're done with it. This can be hard to get right, especially in the context of exception handling.
Use a smart pointer to manage memory for you (auto_ptr, shared_ptr, unique_ptr, etc.)
C++ does not come with a garbage collector, but nothing prevents you from using one (such as the Boehm GC) if you want to go down that route.
That is a memory leak. You have to delete memory you allocate manually.
A = new MyClass();
{...do something in the meantime...}
A = NULL;
The way I keep track of it is that there are two separate objects. Somewhere on the heap, a MyClass instance is allocated by new. And on the stack, there is a pointer named A.
A is just a pointer, there is nothing magical about out, and it doesn't have some special connection to the heap-allocated MyClass object. It just happens to point to that right now, but that can change.
And on the last line, that is exactly what happens. You change the pointer to point to something else. That doesn't affect other objects. It doesn't affect the object it used to point to, and it doesn't affect the object (if any) that it is set to point to now. Again, A is just a dumb raw pointer like any other. It might be NULL, or it might point to an object on the stack, or it might point to an object on the heap, or it might be uninitialized and point to random garbage. But that's all it does. It points, it doesn't in any way take ownership of, or modify, the object it points to.
You need to delete A;
For regular objects setting the pointer to NULL does nothing but invalidating the pointer, the object is still around in memory, this is particularly true if you notice that you may have more than one pointer to the same object, changing one shouldn't affect the others.
On most modern OSs, the application's memory will be reclaimed at exiting the application. Meanwhile, you have a memory leak.
As per Phil Nash's comment, for every new, there is a corresponding delete, likewise, for every malloc, there is a corresponding free. If the corresponding delete/free is not there, you have a leak.
Hope this helps,
Best regards,
Tom.
C++ does't have garbage collector, like some other languages has (Java, C#, ...) so you must delete allocaled objects yourself.
No, it will be lost to the process forever. You will have a memory leak. If you keep doing this, your program will eventually run out of memory!! To avoid this, delete the object when you no longer need it.
Often people will set the pointer to NULL after deleting it, so that other parts of the program can verify that the object has been deleted, and thereby avoid accessing or deleting it again.
Variables stored on the stack, are the local variables of each function, e.g. int big[10];
Variables stored on the heap, are the variables which you initiated using explicit memory allocation routines such as malloc(), calloc(), new(), etc.
Variables stored on the stack have a lifetime that is equal to the lifetime of the current stack frame. In English, when the function returns, you can no longer assume that the variables hold what you expect them to hold. That's why its a classic mistake to return a variable that was declared local in a function.
By assigning NULL to the pointer you will not free allocated memory. You should call deallocation function to free allocated memory. According to C++ Standard 5.3.4/8: "If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete". I could suggest the following function to safely delete pointers (with assigning NULL to them):
template<typename T>
inline void SafeDelete( T*& p )
{
// Check whether type is complete.
// Deleting incomplete type will lead to undefined behavior
// according to C++ Standard 5.3.5/5.
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete p;
p = NULL;
}