Dynamic memory reallocation - c++

If you allocate some space dynamically for example
struct node*py=new struct node;
struct node*tr=py;
delete py;
shouldn't the allocated memory still remain and not be freed since I do have another pointer pointing to the same address before the original pointer to the same is deleted?

No. That's simply not how memory allocation works in C++.
If you allocate memory with new, and then you call delete on it, it will get deleted. The memory manager has no facility for canceling or aborting a deletion once it's begun. C++ has a tendency of doing exactly what you ask it to do, so if you don't really want to free some memory, then don't call delete on it yet.
If you want reference counting, try using std::shared_ptr (or boost::shared_ptr, if you don't have the one in std yet).

no, the heap manager just does what it's told and frees the memory.
If you want to retain the memory based on how many references you have to the memory, then consider using reference-counted pointers such as C++11 shared_ptr (see, e.g., Dr Dobbs) or boost's smart pointers.

But you said it yourself - its only a pointer, therefore it doesnt know to what it points. it simply points to somewhere blindfolded.

No, in c/c++ the compiler/execution environment does not track refrences to memory, new and free mark memory as in use or not in use, and any refrence counting or other higher order garbage collection is left up to your program.

Related

(c++) what happens to objects on the heap that don't have any pointers to them?

do they become memory leaks or does c++ realize they have no pointers aiming at them and free up that memory? If they must be deleted i just use the delete command right?
does c++ realize they have no pointers aiming at them and free up that memory?
C++ does not "realize" any such thing. There is no built-in garbage collector.
If you allocate memory with new and don't free it with a corresponding call to delete, you have a memory leak.
Cody is correct, C++ does not have a garbage collector so you would have a memory leak when the pointer to the object is lost.
C++ does have something in the std library to address this. The std::shared_ptr will automatically delete the object if the object no longer has any std::shared_ptr pointed to it.

What do I have to garbage collect in a C++ destructor

I'm writing a C++ destructor (I hope that's the right term; I'm new to C++) and I'm not positive on what exactly I need to garbage collect. Let's say I have 2 pointers as instance variables do I need to garbage collect them? What about if I have an object as an instance variable? Or a pointer to an object?
I'm just a little fuzzy on what exactly needs to be deleted and what is automatically cleaned up.
Thanks
General rule of thumb is... if you called new, call delete. If you called new[], call delete[]. If you're accessing these pointers outside of the class and effectively sharing them, you'll want to be careful about the "owning" object deleteing the shared objects while they're still in use. Garbage collection isn't quite the right term. You want to destroy the object and free its memory. This is what delete/delete[] does. new/new[] allocate memory and construct an object.
In C++, there is no garbage collector. You must "manually" handle it. That's not to say that it's all tedium. You'll probably get into using smart pointers to handle some of this logic for you. See this question for more information.
You must delete every pointer you allocate with new. It's that simple, and it's that complicated; you must not lose track of any pointer allocated by new until you have deleted it.
Also, you need to make sure that if you use new[] to allocate a pointer, you call delete[] to deallocate it.
It's not about what pointers you happen to have in a class instance. You need to know who owns them (the owner is the one responsible for deleting them). If your object owns those pointers, then it should delete them. If it doesn't own them, then it shouldn't.
This is also why experienced C++ programmers avoid naked pointers where possible. Smart pointers allow you to express ownership types semantically in the language. That way, you don't have to keep track of who owns what; you know who owns it by the type of smart pointer being used.
You must call delete on every space you created using new, delete[] on every area created using new[], and free on everything you got using malloc.
You should also close any sockets you opened, and clear up any other OS resources your class owns.
Note: this is not called garbage collection. Garbage collection is when this process happens automatically, as part of a library or language runtime, not when you do it explicitly.
You should start by learning about "Resource Acquisition is Initialization" (RAII) and smart pointers (shared_ptr and unique_ptr). This is the idiom you have to know in C++ if you come from other languages.
Usual practice says that whatever you allocated in your constructor must be deallocated in your destructor (see other answers to know how). Event better, try to use values as much as possible and new as less as possible.
C++ loves the stack, and stack allocation and deallocation are automatic and cheap (no new, no delete). Use references and const-references instead of pointers.
If you really need dynamic memory, try to use one of the smart pointers.
Any memory you allocate using new operator needs to be freed.
You allocate memory by doing:
int * p1 = new int[5];
p2 = new int;
and you delete it by doing:
delete[] p1
delete p2;
If you are playing with Classes, you need to do the same thing in constructors (allocate) and destructors (deallocate).
In an ideal world, nothing. There are smart pointers and containers for every pattern. Sometimes, you will have to write your own, or augment existing implementations, but much of what you need exists already.
For an array, start with std::array and std::vector. For objects, read up on smart pointers and shared pointers. As a generalization: if you need to call delete, delete[] or free, you have usually headed down the wrong path.
You need to garbage collect all pointers that you don't no longer need. Otherwise you would have the dangling pointer problem.

Do I need to delete an static std::map?

In some classes I have an static std::map with pointers inside. My question is if I need to delete at the end of the program or this memory is automatically freed. My concern is if the pointers stored inside are correctly deleted through our destructors when std::map is deleted.
Thanks.
If the map contains pointers that were allocated with new (or new[], or malloc), then each pointer needs a corresponding delete (or delete[], or free).
The map's destructor wont know what to do with a bald pointer. Consider using a smart pointer that has appropriate move semantics like a boost smart pointer or if you've got a very new compiler, one of the C++0x smart pointers. However, do not use the current standard's std::auto_ptr, inside of STL containers. See this thread for why.
Edit:
As Billy ONeal pointed out, boost::ptr_map is also designed exactly for this purpose.
If I understand the situation correctly, you don't delete the map itself. But you probably need to delete the objects the map is pointing to. It would probably be a really good idea to use a smart pointer such as Boost shared_ptr in your map instead of native pointers. Then the objects would be cleaned up automatically.
Edit:
Using Boost ptr_map might be an even better idea.
The memory is "automatically freed", in the sense that the entire process memory is freed, but the destructors of the objects pointed to will not be called. This can cause a resource leak, if you use RAII.
std::map never calls delete on it's members. Assuming you're working with a relatively recent operating system, the OS will reclaim the memory occupied by the members on process termination, but the destructors will not run.
If you have a map of pointers, then the answer is 'no', your destructors will not be called, but 'yes', the memory will be freed at the end of process execution. All memory allocated by a process is always freed by the Operating System when a process exits (even if it crashes), but destructors might not be called.
A memory "leak" is where memory is unintentionally not deleted over a period of time, and ends up reducing as the process continues. If it is a type of process that runs for a very long period of time, eg a server that is rarely restarted, this can be a major problem.
Memory leak detectors will pick up on any memory that is allocated and not deleted by a programming call, so valgrind, etc. will report this as a leak.
It is as well to check your code with programs like valgrind, and therefore the less that "gets in the way", the easier it will be to spot real leaks. Therefore my advice is not do just let the system clean up the memory, or singletons, etc, for you when you have allocated a pointer with new (or malloc or new[]).
You can have a "clean-up" routine to do this. Just have an object in the scope of your map that has a deleter (as it will be deleted when it exits) that will clean up the pointers in the map. As you need your object to be deleted first it should be declared later than the map.
Like in any case of storage class which stores pointers: you are responsible to deallocate memory they point to. Storage class is responsible only to clean its own resources. Relying on reclaiming memory by OS at the process termination is a bad practice.

Delete pointer to a structure

one of the cpp files has a structure pointer created with "new" operator. Should that pointer be explicitly deleted? Or is the pointer automatically deleted?
C++ does not (normally) have automatic memory management. To free up the memory of that object you would use delete. When to use it is a different question.
EDIT: Also, the pointer will be deleted (or will be overwritten on the stack) when the function returns, but the object pointed at will stay in the heap until you delete it.
The use of the 'new' keyword will allocate memory on the heap, the same way 'malloc' does in C. To get that memory back when you're done using it, you have to do a 'delete' on the pointer returned from the 'new'.
This is easy when the life of some object does not extend outside the function where it was instantiated, but becomes more complicated when these objects are returned or added to collections...
As #Jared Updike notes, you have to do this by yourself. That's one reason why smart pointers such as those in Boost and C++0x are so widely used - they are lightweight classes that manage an underlying raw memory pointer, to avoid memory leaks when (not if) you forget to delete or delete[] raw pointers.
If you are new to C++ do yourself a favour and take a look at those (scoped_ptr, shared_ptr etc).
If you are looking for easier memory management, you may want to look at Shared Pointers . They are a convenient way to assure you that the memory will be freed if correclty used.

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;
}