Dynamically allocated member variable. What's the point? - c++

I'm totally new to C++. I would like to ask about the following.
If a member variable is dynamically allocated in the constructor. Should it always be deleted in destructor? If so, then how is the variable's lifetime "elongated"? If not, how should memory leak be handled otherwise?
I couldn't find any source to address this issue explicitly.

Reasons to allocate a member dynamically are
The size of an array may be non-constant
The member could be very large, such that there is not enough memory on the stack
The member is polymorphic, as commented by MSalters
But, as Alf already pointed out in a comment, it is preferable to use a smart pointer. This has the advantage that you don't need to explicitly delete that member in the destructor, and in the case of a shared_ptr, you can elongate the liftime as needed, the smart pointer takes care of the destruction.

Should it always be deleted in destructor?
Not a necessity - you can free up the memory as soon as the work is done by some other function, if you are sure it won't be used any further. But, you must anyway call this destruction routine from destructor also to avoid memory leak. Ideally, you'd also need to provide another function for ReAllocate the memory.
In short, it all depends on your class and what are you implementing.

Let me take some post-modern approach and say "you don't have to worry about it anymore"
use unique_ptr if only the creating-object is incharge of that resource, use shared_ptr if many objects share that resource. use STL containers for all other possible uses.
use new and delete only if you're writing something extremely low-level or implementing a container from scratch. for all other cases, view dynamic memory allocation (via malloc and new) as deprecated.

Related

Will using shared_ptr for returning pointers from a method always save me from memory leaks?

I'm a c++ newbie, my code currently new's up on the heap in several places without calling delete. I know I need to do something about this.
My typical usage is where I new up a class instance in another classes member method then the method returns the pointer to the object.
If i change the return types from MyType* to std::tr1::shared_ptr will this fix my code to not leak memory?
Thanks a lot.
Edit:
Also likewise, I currently store new'ed up objects as MyType* as a value in a std:map. This map is a private member to a class instance. If I simply change this to std::tr1::shared_ptr will this clear up these when it's owner (class) falls out of scope?
Thanks again
It's a reasonable band-aid, sure.
A shared pointer is a reference-counted pointer. So as long as one or more shared_ptrs exist pointing to an object, that object will be kept alive. The problem occurs if you have circular references. Then the reference count will never reach 0, and the object(s) will never be deleted.
So shared_ptr * still* require you to understand what you're doing and think about object ownership, as you always have to do in C++. But it simplifies some otherwise complex scenarios, where determining ownership is hard.
But the real fix to your problem is to:
minimize how much you allocate with new. Can the object instead be stored on the stack? Can the object be rewritten as a RAII class, so that a small wrapper object is allocated on the stack (or elsewhere with automatic storage duration), and which, through its constructors and destructors, manages a heap-allocated memory resource? Then, as long as that object exists, its allocated memory will be preserved, and once it is destroyed, it will delete its allocated memory.
when you allocate objects with new, put them in one of the smart pointer classes. shared_ptr is popular because it is the one that comes closest to looking like a garbage collector, but it isn't, and if you treat it as one and use it as an excuse to not think about memory management, then it won't work. Understand all the smart pointer classes (scoped_ptr and auto_ptr in C++03, or unique_ptr replacing both in C++11, shared_ptr and weak_ptr), and use the one that best fits your scenario.
think about ownership. Any time you allocate memory, you need to determine an owner, whose lifetime will control the lifetime of the memory allocation. Think about how long a lifetime your allocation needs, and have another object (whose lifetime is automatically managed, probably because it is on the stack) delete your memory when its destructor is called.
There's no quick and easy fix. The way to handle memory management in C++ is to avoid memory management. Delegate it out to your objects. If you're calling delete in your own code, you're doing it wrong. Often, you don't even need new, but if you do, assign ownership to a smart pointer immediately, and let that call delete for you.
As a rule of thumb, unless you're a library writer, you shouldn't write either new or delete. You should virtually never use raw pointers, and only when it is absolutely necessary, use smart pointers. Let your classes do the heavy lifting. Don't be afraid to put them on the stack, pass them by value, and let them handle their resources internally.
If you are new to C++ there are a few points with pointer management you need to understand and accept, regardless of whether you're using shared_ptr or not.
It is more than likely in your use of C++ you will need to use new and assign its return pointer to a class pointer that you have declared. I believe it is advisable to take the time to understand what is going on there, even if you write a small test program and watch the constructor execute in the debugger.
If you use classes like std::string, its constructors and destructor will do string pointer management for you, but I believe it is a good idea to understand what is going on behind the scenes in that class, if nothing more than reading the documentation.
As another example, you cannot use some classes, without a lot of detailed reading of the API, or you'll get problems. I once worked at company that used a commercial class package years ago. Someone had written a multi-threaded program using this package's thread pool class.
The documentation clearly said you can't just exit with outstanding threads. Yet I saw where the author of the program did not bother to synch up and shutdown all threads on exit, and wound up throwing exceptions, when their program exited. And this was on a commercial financial product.
My suggestion is don't look to get saved from performing pointer management. There are std classes like string that can reduce your headaches, but nothing will prevent problems other than your own diligence and testing.
As long as you understand how tr1 shared pointers work, yes.
Look at Boost C++ shared_ptr<> also - it might be more what you want.

How to properly define destructor

I am relatively new to C++ (and programming in general) so please forgive me if the question is not perfectly clear immediately.
What I have is a program in which a certain number of objects of a internally defined class [let's call this "class1"] are created.
The program works perfectly fine and the objects do what they should.
The problem that I am currently trying to solve is the following: these objects are not destroyed (and thus memory is not de-allocated) until the program exits, but I need that memory earlier.
Among the other members of the class there are objects of other internally defined classes (who also have members that are objects of a third class).
My question is the following: how do I properly define a destructor for the objects of "class1" so that all the data is cancelled and the memory deallocated?
I found out (probably this was obvious for you already) that a destructor like
class1::~class1(void) {
}
won't work (I defined similar destructors for all internally defined classes).
Reading around I understood that my mistake could be that that is a destructor that does nothing. How do I solve this?
Thanks to anyone who will answer/help/comment.
Federico
In C++ you need to free the memory manually. There's no garbage collector. You obviously need to free the memory manually inside your destructor. If you allocated the memory using new, you need to use delete for each resource you allocated with new inside the deconstructor, for example:
class1::~class1(void)
{
delete resource1;
delete resource2;
etc...
}
If you are allocating memory dynamically you need to free it in destructor, but better solution would be to use some smart pointer to hold dynamic data - std::auto_ptr or std::shared_ptr. Then you will not need to explicitly free memory - this will be done automatically in smart pointer destructor.
First you should try to allocate your objects on the stack:
Object obj;
so you don't have to worry about memory allocation. The disadvantage is that the object life is limited to the current scope.
If that's not good for you, you should consider using smart pointers. If that's not an option use new / delete to create / destroy your objects. But you have to be careful, every new should lead to a delete at some point in time..
Memory on stack
If there is no heap-allocated object inside your class, there is no need for you to explicitly define the destructor of your class. The compiler-generated one should handle the job quite well, i.e., call destructors for base class objects and member objects, etc.
Memory on heap - manual memory management
If there is any heap-allocated objects inside your class, you need manually deallocate them in your destructor. Make sure you have them deallocated properly at all possible exit points, e.g., handle exceptions and deallocate resources.
Memory on heap - RAII
Alternatively, you may use some well-defined RAII class to handle the resource management for you automatically, e.g., scoped_ptr, scoped_array in Boost, shared_ptr in STL, etc.

Does memory that is allocated in a function get freed when function returns?

I have a function that allocates memory using the new keyword.
That array gets returned from the function, but I need to somehow free it. Is it ever freed after the function returns, or is it up to the receiving code to free the array after it is done with it?
Should I just make this array a member variable, and free it in the class destructor?
If you allocate memory explicitly with new, you must free it explicitly with delete. Local variables will be freed upon return; classes like vector may do some allocation behind the scenes but they will clean that up for you.
In general, C++ largely lets you pick your memory management model. You can stick with locals and non-pointer class members and get scope-based allocation. You can play with pointers and malloc/free or new/delete (but never free() a new'd pointer and vice versa!). Or, you could grab Boost and get boost::shared_ptr for reference counting semantics.
Should I just make this array a member variable, and free it in the class deconstructor?
That's generally a very good idea, but why reinvent the wheel? Just use std::vector<T>.
It depends. You need to define who has got the ownership of such object.
You can allocate the array in your function, return it, and let the caller free it, or put a pointer to it in a class which will destroy the pointer in the destructor.
If the ownership for such object should be shared among many entities you should use something like a shared_ptr.
I'd also suggest to always use some kind of smart pointer to handle your raw pointers.
Take a look at boost::shared_array. It does what you need.
Either that, or use std::vector

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.

When should I use the new keyword in C++?

I've been using C++ for a short while, and I've been wondering about the new keyword. Simply, should I be using it, or not?
With the new keyword...
MyClass* myClass = new MyClass();
myClass->MyField = "Hello world!";
Without the new keyword...
MyClass myClass;
myClass.MyField = "Hello world!";
From an implementation perspective, they don't seem that different (but I'm sure they are)... However, my primary language is C#, and of course the 1st method is what I'm used to.
The difficulty seems to be that method 1 is harder to use with the std C++ classes.
Which method should I use?
Update 1:
I recently used the new keyword for heap memory (or free store) for a large array which was going out of scope (i.e. being returned from a function). Where before I was using the stack, which caused half of the elements to be corrupt outside of scope, switching to heap usage ensured that the elements were intact. Yay!
Update 2:
A friend of mine recently told me there's a simple rule for using the new keyword; every time you type new, type delete.
Foobar *foobar = new Foobar();
delete foobar; // TODO: Move this to the right place.
This helps to prevent memory leaks, as you always have to put the delete somewhere (i.e. when you cut and paste it to either a destructor or otherwise).
Method 1 (using new)
Allocates memory for the object on the free store (This is frequently the same thing as the heap)
Requires you to explicitly delete your object later. (If you don't delete it, you could create a memory leak)
Memory stays allocated until you delete it. (i.e. you could return an object that you created using new)
The example in the question will leak memory unless the pointer is deleted; and it should always be deleted, regardless of which control path is taken, or if exceptions are thrown.
Method 2 (not using new)
Allocates memory for the object on the stack (where all local variables go) There is generally less memory available for the stack; if you allocate too many objects, you risk stack overflow.
You won't need to delete it later.
Memory is no longer allocated when it goes out of scope. (i.e. you shouldn't return a pointer to an object on the stack)
As far as which one to use; you choose the method that works best for you, given the above constraints.
Some easy cases:
If you don't want to worry about calling delete, (and the potential to cause memory leaks) you shouldn't use new.
If you'd like to return a pointer to your object from a function, you must use new
There is an important difference between the two.
Everything not allocated with new behaves much like value types in C# (and people often say that those objects are allocated on the stack, which is probably the most common/obvious case, but not always true). More precisely, objects allocated without using new have automatic storage duration
Everything allocated with new is allocated on the heap, and a pointer to it is returned, exactly like reference types in C#.
Anything allocated on the stack has to have a constant size, determined at compile-time (the compiler has to set the stack pointer correctly, or if the object is a member of another class, it has to adjust the size of that other class). That's why arrays in C# are reference types. They have to be, because with reference types, we can decide at runtime how much memory to ask for. And the same applies here. Only arrays with constant size (a size that can be determined at compile-time) can be allocated with automatic storage duration (on the stack). Dynamically sized arrays have to be allocated on the heap, by calling new.
(And that's where any similarity to C# stops)
Now, anything allocated on the stack has "automatic" storage duration (you can actually declare a variable as auto, but this is the default if no other storage type is specified so the keyword isn't really used in practice, but this is where it comes from)
Automatic storage duration means exactly what it sounds like, the duration of the variable is handled automatically. By contrast, anything allocated on the heap has to be manually deleted by you.
Here's an example:
void foo() {
bar b;
bar* b2 = new bar();
}
This function creates three values worth considering:
On line 1, it declares a variable b of type bar on the stack (automatic duration).
On line 2, it declares a bar pointer b2 on the stack (automatic duration), and calls new, allocating a bar object on the heap. (dynamic duration)
When the function returns, the following will happen:
First, b2 goes out of scope (order of destruction is always opposite of order of construction). But b2 is just a pointer, so nothing happens, the memory it occupies is simply freed. And importantly, the memory it points to (the bar instance on the heap) is NOT touched. Only the pointer is freed, because only the pointer had automatic duration.
Second, b goes out of scope, so since it has automatic duration, its destructor is called, and the memory is freed.
And the barinstance on the heap? It's probably still there. No one bothered to delete it, so we've leaked memory.
From this example, we can see that anything with automatic duration is guaranteed to have its destructor called when it goes out of scope. That's useful. But anything allocated on the heap lasts as long as we need it to, and can be dynamically sized, as in the case of arrays. That is also useful. We can use that to manage our memory allocations. What if the Foo class allocated some memory on the heap in its constructor, and deleted that memory in its destructor. Then we could get the best of both worlds, safe memory allocations that are guaranteed to be freed again, but without the limitations of forcing everything to be on the stack.
And that is pretty much exactly how most C++ code works.
Look at the standard library's std::vector for example. That is typically allocated on the stack, but can be dynamically sized and resized. And it does this by internally allocating memory on the heap as necessary. The user of the class never sees this, so there's no chance of leaking memory, or forgetting to clean up what you allocated.
This principle is called RAII (Resource Acquisition is Initialization), and it can be extended to any resource that must be acquired and released. (network sockets, files, database connections, synchronization locks). All of them can be acquired in the constructor, and released in the destructor, so you're guaranteed that all resources you acquire will get freed again.
As a general rule, never use new/delete directly from your high level code. Always wrap it in a class that can manage the memory for you, and which will ensure it gets freed again. (Yes, there may be exceptions to this rule. In particular, smart pointers require you to call new directly, and pass the pointer to its constructor, which then takes over and ensures delete is called correctly. But this is still a very important rule of thumb)
The short answer is: if you're a beginner in C++, you should never be using new or delete yourself.
Instead, you should use smart pointers such as std::unique_ptr and std::make_unique (or less often, std::shared_ptr and std::make_shared). That way, you don't have to worry nearly as much about memory leaks. And even if you're more advanced, best practice would usually be to encapsulate the custom way you're using new and delete into a small class (such as a custom smart pointer) that is dedicated just to object lifecycle issues.
Of course, behind the scenes, these smart pointers are still performing dynamic allocation and deallocation, so code using them would still have the associated runtime overhead. Other answers here have covered these issues, and how to make design decisions on when to use smart pointers versus just creating objects on the stack or incorporating them as direct members of an object, well enough that I won't repeat them. But my executive summary would be: don't use smart pointers or dynamic allocation until something forces you to.
Which method should I use?
This is almost never determined by your typing preferences but by the context. If you need to keep the object across a few stacks or if it's too heavy for the stack you allocate it on the free store. Also, since you are allocating an object, you are also responsible for releasing the memory. Lookup the delete operator.
To ease the burden of using free-store management people have invented stuff like auto_ptr and unique_ptr. I strongly recommend you take a look at these. They might even be of help to your typing issues ;-)
If you are writing in C++ you are probably writing for performance. Using new and the free store is much slower than using the stack (especially when using threads) so only use it when you need it.
As others have said, you need new when your object needs to live outside the function or object scope, the object is really large or when you don't know the size of an array at compile time.
Also, try to avoid ever using delete. Wrap your new into a smart pointer instead. Let the smart pointer call delete for you.
There are some cases where a smart pointer isn't smart. Never store std::auto_ptr<> inside a STL container. It will delete the pointer too soon because of copy operations inside the container. Another case is when you have a really large STL container of pointers to objects. boost::shared_ptr<> will have a ton of speed overhead as it bumps the reference counts up and down. The better way to go in that case is to put the STL container into another object and give that object a destructor that will call delete on every pointer in the container.
Without the new keyword you're storing that on call stack. Storing excessively large variables on stack will lead to stack overflow.
If your variable is used only within the context of a single function, you're better off using a stack variable, i.e., Option 2. As others have said, you do not have to manage the lifetime of stack variables - they are constructed and destructed automatically. Also, allocating/deallocating a variable on the heap is slow by comparison. If your function is called often enough, you'll see a tremendous performance improvement if use stack variables versus heap variables.
That said, there are a couple of obvious instances where stack variables are insufficient.
If the stack variable has a large memory footprint, then you run the risk of overflowing the stack. By default, the stack size of each thread is 1 MB on Windows. It is unlikely that you'll create a stack variable that is 1 MB in size, but you have to keep in mind that stack utilization is cumulative. If your function calls a function which calls another function which calls another function which..., the stack variables in all of these functions take up space on the same stack. Recursive functions can run into this problem quickly, depending on how deep the recursion is. If this is a problem, you can increase the size of the stack (not recommended) or allocate the variable on the heap using the new operator (recommended).
The other, more likely condition is that your variable needs to "live" beyond the scope of your function. In this case, you'd allocate the variable on the heap so that it can be reached outside the scope of any given function.
The simple answer is yes - new() creates an object on the heap (with the unfortunate side effect that you have to manage its lifetime (by explicitly calling delete on it), whereas the second form creates an object in the stack in the current scope and that object will be destroyed when it goes out of scope.
Are you passing myClass out of a function, or expecting it to exist outside that function? As some others said, it is all about scope when you aren't allocating on the heap. When you leave the function, it goes away (eventually). One of the classic mistakes made by beginners is the attempt to create a local object of some class in a function and return it without allocating it on the heap. I can remember debugging this kind of thing back in my earlier days doing c++.
C++ Core Guidelines R.11: Avoid using new and delete explicitly.
Things have changed significantly since most answers to this question were written. Specifically, C++ has evolved as a language, and the standard library is now richer. Why does this matter? Because of a combination of two factors:
Using new and delete is potentially dangerous: Memory might leak if you don't keep a very strong discipline of delete'ing everything you've allocated when it's no longer used; and never deleteing what's not currently allocated.
The standard library now offers smart pointers which encapsulate the new and delete calls, so that you don't have to take care of managing allocations on the free store/heap yourself. So do other containers, in the standard library and elsewhere.
This has evolved into one of the C++ community's "core guidelines" for writing better C++ code, as the linked document shows. Of course, there exceptions to this rule: Somebody needs to write those encapsulating classes which do use new and delete; but that someone is rarely yourself.
Adding to #DanielSchepler's valid answer:
The second method creates the instance on the stack, along with such things as something declared int and the list of parameters that are passed into the function.
The first method makes room for a pointer on the stack, which you've set to the location in memory where a new MyClass has been allocated on the heap - or free store.
The first method also requires that you delete what you create with new, whereas in the second method, the class is automatically destructed and freed when it falls out of scope (the next closing brace, usually).
The short answer is yes the "new" keyword is incredibly important as when you use it the object data is stored on the heap as opposed to the stack, which is most important!