I am writing a template class that takes as an input a pointer and stores it. The pointer is meant to point to an object allocated by another class, and handed to the this containing class.
Now I want to create a destructor for this container. How should I free the memory pointed to by this pointer? I have no way of knowing a priori whether it is an array or a single element.
I'm sort of new to C++, so bear with me. I've always used C, and Java is my OO language of choice, but between wanting to learn C++ and the speed requirements of my project, I've gone with C++.
Would it be a better idea to change the container from a template to a container for an abstract class that can implement its own destructor?
If you don't know whether it was allocated with new or new[], then it is not safe to delete it.
Your code may appear to work. For example, on one platform I work on, the difference only matters when you have an array of objects that have destructors. So, you do this:
// by luck, this works on my preferred platform
// don't do this - just an example of why your code seems to work
int *ints = new int[20];
delete ints;
but then you do this:
// crashes on my platform
std::string *strings = new std::string[10];
delete strings;
You must document how this class expects to be used, and always allocate as expected. You can also pass a flag to the object specifying how it should destroy. Also look at boost's smart pointers, which can handle this distinction for you.
Short answer:
If you use [] with new you want to use [] with delete.
//allocate some memory
myObject* m = new myObject[100];
//later on...destructor...
delete m; //wrong
delete[] m; //correct
That was the bare bones, the other thing you could look at is boost. Also quite difficult to answer considering you are not sure if its an array or single object. You could check this though via a flag telling your app whether to use delete or delete[].
As a general development rule, you should stick to a design where the class which calls new should also call delete
You shouldn't delete it at all. If your class takes an already initialized pointer, it is not safe to delete it. It might not even point to an object on the heap; calling either delete or delete[] could be disastrous.
The allocation and deallocation of memory should happen in the same scope. Which ever code owns and initializes the instance of your class is also presumably responsible for initializing and passing in the pointer, and that is where your delete should be.
Use delete if you allocated with new.
Use delete[] if you allocated with new[].
After these statements, if you still have a problem (maybe you want to delete an object that was created by someone else), then you are breaking the third rule:
Always delete what you created. Corollary, never delete what you did not create.
(Moving my comment into an answer, by request.)
JonH's answer is right (about using array destruction only when you used array construction), so perhaps you should offer templates: one for arrays, one not.
The other answer is to avoid arrays and instead expect a single instance that may or may not be a proper collection that cleans up after itself, such as vector<>.
edit
Stealing blatantly from Roger Pate, I'll add that you could require the use of a smart pointer, which amounts to a single-item collection.
If you have a class that takes a pointer it's going assume ownership of, then the contract for the use of the class needs to include one of a couple things. Either:
the interface needs to indicate how the object the pointer is pointing to was allocated so the new owner can know how to safely deallocate the object. This option has the advantage of keeping things simple (on one level anyway), but it's not flexible - the class can't handle taking ownership of static objects as well as dynamically allocated objects.
or
the interface needs to include a mechanism where a deallocation policy can be specified by whatever is giving the pointer to the class. This can be as simple as providing a mechanism to pass in a functor (or even a plain old function pointer) that will be called to deallocate the object (preferably in the same function/constructor that passes in the pointer itself). This makes the class arguably more complicated to use (but having a default policy of calling delete on the pointer, for example, might make it as easy to use as option 1 for the majority of uses). Now if someone wants to give the class a pointer to a statically allocated object, they can pass in a no-op functor so nothing happens when the class wants to deallocates it, or a functor to a delete[] operation if the object was allocated by new[], etc.
Since pointer in C++ does not tell us how it was allocated, yes, there's no way to decide what deallocation method to use. The solution is to give the choice to the user that hopefully knows how the memory was allocated. Take a look at Boost smart ptr library, especially at shared_ptr constructor with second parameter, for a great example.
A smart pointer like boost shared_pointer already has this covered, could you use it? linky
Put simply, given only a pointer to dynamically allocated memory there is no way of determining how to de-allocate it safely. The pointer could have been allocated in any of the the following ways:
using new
using new []
using malloc
using a user defined function
etc.
In all cases before you can deallocate the memory you have to know how it was allocated.
Related
I have to write an application to complete an assignment, at school. To do so, we have to create a dynamic array. My question is:
If I create a structure containing a dynamic pointer, and copy it, does the memory get copied too?
For instance:
struct SomePointerStruct
{
int* p_array;
}
What happens if I copy that structure? Also,
Do I need to clean up the original pointer?
By default, objects in c++ are copied byte-by-byte. that means that the pointer will be copied, and you will get two pointers pointing to the same array.
To fix this, you need to implement a copy constructor and should also override the operator=. Also, you may want to delete this array when you finish, so implement also a destructor. That is "the rule of three".
If I create a structure containing a dynamic pointer, and copy it,
does the memory get copied too?
No.
Much of the design of the C++ language is dictated by the edict, "You don't pay for what you don't need." One way this plays out is if you want to deep-copy something, you have to do it yourself.
Do I need to clean up the original pointer?
In general, yes.
For every new, there must be exactly one matching delete. If you instantiate a SomePointerStruct, and the construction of that calls new, that's one delete you need somewhere -- probably in SomePointerStruct's destructor. If you create a copy of SomePointerStruct and the copy deep-copies the original pointer (calling new), then that's a second delete you need -- again, probably in the destructor.
To avoid repeating the whole chapter named Memory from your C++ book, I'll answer with that:
Raw pointers shouldn't own memory.
By consequence:
struct SomePointerStruct { int x; }
is trivially copyable, and:
struct SomePointerStruct { std::unique_ptr<int> x; }
is noncopyable (but it's moveable). That extends to all of your other types (if they are properly constructed), sans the "trivially", perhaps. The fact that the pointer value would be copied in your original example would of course lead to a lot of problems, but since they can be easily avoided by using what I wrote above, it's kind of off the scope WRT such a simple assignment.
A whole another thing would be a non-owning pointer case, in which a copied struct would, of course, point to the same region of memory. You lose all the guarantees of the pointer pointing to a valid location, though, so a reference would be preferred.
As for creating of a dynamic array, you'd be best off with simply using std::vector.
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.
What's a good policy for when to use "new" to make an instance of a class? I've been hobby programming C++ for a while but I'm still not for sure when is the best time to do this:
MyClass thing(param1, param2);
over this:
MyClass* thing;
thing = new MyClass(param1, param2);
Any advice?
Design-wise, use automatic (stack) allocation as much as possible. Whenever you need to extend the lifetime of an object beyond a certain scope, then dynamically allocate it.
And even so, never dynamically allocate things raw. Always keep them wrapped into some sort of wrapper that implements Scope-Bound Resource Management (SBRM, first known under the dumb/awkward name Resource-Acquisition Is Initialization or RAII.) That is, dynamic allocations should be kept in automatic objects that will clean up automatically!
A good example of this is std::vector: you cannot leak the memory internal to a vector, because it's destructor is run in every scenario when memory should be free'd, and it will free it for you. auto_ptr is the first and only smart pointer available in the standard library, but it's pretty bad. Better is to use shared_ptr, or many of the other popular smart pointers available in Boost and/or TR1 and/or C++0x.
Performance-wise, objects allocated on the stack can be done so very quickly (the stack size is increased per-function-call, so all the required memory has been allocated up-front by a simple move of a pointer.) Contrarily, dynamic allocation generally requires much more time. It's quite possible to get speedy dynamic allocations with custom allocation schemes, but even the best will still be slower than stack allocation.
Occasionally, you might find you spend too much time copying objects around. In this case, it may be worth it to dynamically allocate it and merely move pointers around. However, please note I said "find". This kind of change is something you find by profiling and measuring, never guessing.
So: Automatic allocation when possible, dynamic allocation when needed.
The first approach creates a local instance on the stack that goes away when the calling function exits. The second creates an instance that stays on the heap until (and if) you explicitly release it again. The choice depends on what kind of control and lifetime you want for your object.
The rule of thumb is: if it works without new, don't use new.
In general: you don't need to use new if you plan to delete the object in the same scope. If the object is quite large, you may want to use new.
You may want to look into the difference between heap and stack memory if you want to know the details.
First, ask yourself the question, does it make sense for the object to be copied when another function wants it?
If it makes sense to copy the object, your best bet is to create everything on the stack or as member variables and then just pass copies around when needed.
If it does not make sense to copy the object, you'll need to use new form so that you can safely pass the pointer to the object. You have to use a pointer (or reference) because as noted it does not make sense to copy the object.
There are two exceptions I'm aware of:
If you know the object isn't going to be used after the current function is finished, you can create the object on the stack so that it is deleted. Just make very sure nobody holds on to a pointer to it afterwards! (I rarely find this is the case, but it happens)
If the object is used internally by another class which itself shouldn't be copied around, you can just put it in as a member variable. Since the object it is in won't be copied, and its only for internal use that will be safe.
MyClass thing(param1, param2); //memory for thing is allocated on the process stack(static allocation)
MyClass* thing;
thing = new MyClass(param1, param2); //memory is allocated dynamically on the heap(free store) for thing
The difference lies here:
int main()
{
{
MyClass thing(param1, param2); //thing is local to the scope
} //destructor called for thing
//cannot access thing (thing doesn't exist)
}
int main()
{
{
MyClass* thing;
thing = new MyClass(param1, param2);
}
//the object pointed to by thing still exists
//Memory leak
}
For large objects you must allocate memory dynamically(use new) because the process stack has a limited size.
I am pretty proficient with C, and freeing memory in C is a must.
However, I'm starting my first C++ project, and I've heard some things about how you don't need to free memory, by using shared pointers and other things.
Where should I read about this? Is this a valuable replacement for proper delete C++ functionality? How does it work?
EDIT
I'm confused, some people are saying that I should allocate using new and use smart pointers for the deallocation process.
Other people are saying that I shouldn't allocate dynamic memory in the first place.
Others are saying that if I use new I also have to use delete just like C.
So which method is considered more standard and more-often used?
Where should I read about this?
Herb Sutter's Exceptional C++ and Scott Meyers's More Effective C++ are both excellent books that cover the subject in detail.
There is also a lot of discussion on the web (Google or StackOverflow searches for "RAII" or "smart pointer" will no doubt yield many good results).
Is this a valuable replacement for proper delete C++ functionality?
Absolutely. The ability not to worry about cleaning up resources, especially when an exception is thrown, is one of the most valuable aspects of using RAII and smart pointers.
What I meant in my comment (sorry for being terse - I had to run out to the shops) is that you should be using:
std::string s = "foobar";
rather than:
std::string * s = new std::string( "foobar" );
...
delete s;
and:
vector <Person> p;
p.push_back( Person( "fred" ) );
rather than:
vector <Person *> p;
p.push_back( new Person( "fred" ) );
You should always be using classes that manage memory for you. In C++ the main reason for creating an object using new is that you don't know its type at compile-time. If that isn't the reason, think long and hard before using new and delete, or even smart pointers.
If you allocate dynamic memory (with new), you need to free it (with delete), just like using malloc/free in C. The power of C++ is that it gives you lots of ways of NOT calling new, in which case you don't need to call delete.
You still have to worry about freeing memory in C++, it's just that there are better methods/tools for doing so. One can argue that attention to memory management in C++ is more difficult as well due to the added requirement of writing exception safe code. This makes things such as:
MyClass *y = new MyClass;
doSomething(y);
delete y;
Look completely harmless until you find that doSomething() throws an exception and now you have a memory leak. This becomes even more dangerous as code is maintained as the code above could have been safe prior to someone changing the doSomething() function in a later release.
Following the RAII methodology is a big part of fixing memory management challenges and using auto_ptr's or shared pointers provided by libraries such as Boost make it easier to incorporate these methods into your code.
Note that auto_ptr is not a "shared" pointer. It is an object that takes ownership of the dynamically allocated object and gives that ownership away on assignment and copy. It doesn't count references to the memory. This makes it unsuitable for use within standard containers and many in general prefer the shared_ptr of Boost to the auto_ptr provided by the standard.
It is never safe to put auto_ptrs into
standard containers. Some people will
tell you that their compiler and
library compiles this fine, and others
will tell you that they've seen
exactly this example recommended in
the documentation of a certain popular
compiler; don't listen to them.
The problem is that auto_ptr does not
quite meet the requirements of a type
you can put into containers, because
copies of auto_ptrs are not
equivalent. For one thing, there's
nothing that says a vector can't just
decide to up and make an "extra"
internal copy of some object it
contains. For another, when you call
generic functions that will copy
elements, like sort() does, the
functions have to be able to assume
that copies are going to be
equivalent. At least one popular sort
internally takes a copy of a "pivot"
element, and if you try to make it
work on auto_ptrs it will merrily take
a copy of the pivot auto_ptr object
(thereby taking ownership and putting
it in a temporary auto_ptr on the
side), do the rest of its work on the
sequence (including taking further
copies of the now-non-owning auto_ptr
that was picked as a pivot value), and
when the sort is over the pivot is
destroyed and you have a problem: At
least one auto_ptr in the sequence
(the one that was the pivot value) no
longer owns the pointer it once held,
and in fact the pointer it held has
already been deleted!
Taken From: Using auto_ptr Effectively
Well, of course you need to delete. I would rephrase this as 'what libraries can I use that can automate the deletion of allocated memory?'. I'd recommend you start by reading up the Boost Smart pointers page.
The best answer I can give you is: something needs to call delete for each object created with new. Whether you do it manually, or using a scope-based smart pointer, or a reference-counted smart pointer, or even a non-deterministic garbage collector, it still needs to be done.
Having said that, I have not manually called delete in 10 years or so. Whenever I can I create an automatic object (on the stack); when I need to create an object on the heap for some reason I try using a scope-based smart pointer, and in rare cases when there is a legitimate reason to have shared ownership, I use a reference counted smart pointer.
This is a great question, and actually several in one:
Do I need to worry about Managing Memory?
Yes! There is no garbage collection in C++. Anytime you allocate something with new you need to either call delete in your own code, or delegate that responsibility to something like a smart pointer.
When Should I use dynamic memory allocation?
The reasons you'd want to use dynamic memory allocation (allocating with new). Some of these include:
You don't know the size of the thing you are allocating at compile time
You don't know the type of the thing you are allocating at compile time
You are reusing the same data in different contexts and don't want to pay the performance overhead of copying that data around.
There are lots of other reasons, and these are gross over generalizations, but you get the idea.
What tools can I use to help me with memory management?
Smart pointers are the way to go here. A smart pointer will take ownership of memory that you allocate, and then release that memory automatically for you at a specific time depending on the policy the smart pointer.
For example, a boost::scoped_ptr will deallocate memory for you when it goes out of scope
{
scoped_ptr<MyClass> myVar( new MyClass() );
// do Something with myVar
} // myVar goes out of scope and calls delete on its MyClass
In general you should use smart pointers over raw pointers anytime you can. It will save you years of tracking down memory leaks.
Smart pointers come in many forms including:
std::auto_ptr
Boost Smart Pointers
If you can use Boost smart pointers I would. They rock!
Since C++ does not have a garbage collector built into the language, you need to be aware of what memory you have dynamically allocated and how that memory is being freed.
That said, you can use smart pointers to alleviate the problem of having to manually free memory via delete - for example, see Smart Ponters (boost).
First and foremost, before you get into the business of using auto_ptr's and writing your own RAII classes, learn to use the Standard Template Library. It provides many common container classes that automatically allocate their internal memory when you instantiate them and free it up when they go out of scope - things like vectors, lists, maps, and so forth. When you employ STL, using the new-operator and delete (or malloc and free) is rarely necessary.
Freeing memory in C++ is just as much a must as in C.
What you may be thinking of is a smart pointer library (the standard library's auto_ptr among others) - which will do reference counting for you.
'm confused, some people are saying
that I should allocate using new and
use smart pointers for the
deallocation process.
They're right. Just like in C you still need to manage all your memory one way or another. however there are ways to use the language to automate delete.
Smart pointers are basically local scope wrappers for pointers which use the object .dtor to delete the corresponding pointer once the smart pointer - which is like any other objecton the stack - goes out of scope
The beauty of C++ is that you have explicit control over when things are created and when things are destroyed. Do it right and you will not have issues with memory leaks etc.
Depending on your environment, you may want to create objects on the stack or you may want to dynamically allocated (create them on the 'heap' - heap in quotes because its an overused term but is good enough for now).
Foo x; // created on the stack - automatically destroyed when the program exits that block of code it was created in.
Foo *y = new Foo; // created on the heap - its O.K. to pass this one around since you control when its destroyed
Whenever you use 'new', you should use the corresponding version of delete... somewhere, somehow. If you use new to initialize a smart pointer like:
std::auto_ptr x = new Foo;
You are actually creating two items. An instance of auto_ptr and an instance of Foo. auto_ptr is created on the stack, Foo on the heap.
When the stack 'unwinds', it will automatically call delete on that instance of Foo. Automatically cleaning it up for you.
So, general rule of thumb, use the stack version whenever possible/practical. In most instances it will be faster as well.
In order of preference, you should:
Avoid handling allocation yourself at all. C++'s STL (standard template library) comes with a lot of containers that handle allocation for you. Use vector instead of dynamically allocated arrays. Use string instead of char * for arrays of characters. Try to seek out an appropriate container from the STL rather than designing your own.
If you are designing your own class and honestly need dynamic allocation (and you usually won't if you compose your class using members of the STL), place all instances of new (new[]) in your constructor and all instances of delete (delete[]) in your destructor. You shouldn't need malloc and free, generally.
If you are unable to keep your allocations paired within constructors and destructors, use smart pointers. Really this is not so different from #2; smart pointers are basically just special classes which use destructors to ensure deallocation happens.
While learning different languages, I've often seen objects allocated on the fly, most often in Java and C#, like this:
functionCall(new className(initializers));
I understand that this is perfectly legal in memory-managed languages, but can this technique be used in C++ without causing a memory leak?
Your code is valid (assuming functionCall() actually guarantees that the pointer gets deleted), but it's fragile and will make alarm bells go off in the heads of most C++ programmers.
There are multiple problems with your code:
First and foremost, who owns the pointer? Who is responsible for freeing it? The calling code can't do it, because you don't store the pointer. That means the called function must do it, but that's not clear to someone looking at that function. Similarly, if I call the code from somewhere else, I certainly don't expect the function to call delete on the pointer I passed to it!
If we make your example slightly more complex, it can leak memory, even if the called function calls delete. Say it looks like this: functionCall(new className(initializers), new className(initializers)); Imagine that the first one is allocated successfully, but the second one throws an exception (maybe it's out of memory, or maybe the class constructor threw an exception). functionCall never gets called then, and can't free the memory.
The simple (but still messy) solution is to allocate memory first, and store the pointer, and then free it in the same scope as it was declared (so the calling function owns the memory):
className* p = new className(initializers);
functionCall(p);
delete p;
But this is still a mess. What if functionCall throws an exception? Then p won't be deleted. Unless we add a try/catch around the whole thing, but sheesh, that's messy.
What if the function gets a bit more complex, and may return after functionCall but before delete? Whoops, memory leak. Impossible to maintain. Bad code.
So one of the nice solutions is to use a smart pointer:
boost::shared_ptr<className> p = boost::shared_ptr<className>(new className(initializers));
functionCall(p);
Now ownership of the memory is dealt with. The shared_ptr owns the memory, and guarantees that it'll get freed. We could use std::auto_ptr instead, of course, but shared_ptr implements the semantics you'd usually expect.
Note that I still allocated the memory on a separate line, because the problem with making multiple allocations on the same line as you make the function call still exists. One of them may still throw, and then you've leaked memory.
Smart pointers are generally the absolute minimum you need to handle memory management.
But often, the nice solution is to write your own RAII class.
className should be allocated on the stack, and in its constructor, make what allocations with new are necessary. And in its destructor, it should free that memory. This way, you're guaranteed that no memory leaks will occur, and you can make the function call as simple as this:
functionCall(className(initializers));
The C++ standard library works like this. std::vector is one example. You'd never allocate a vector with new. You allocate it on the stack, and let it deal with its memory allocations internally.
Yes, as long as you deallocate the memory inside the function. But by no means this is a best practice for C++.
It depends.
This passes "ownership" of the memory to functionCAll(). It will either need to free the object or save the pointer so that it can be freed later. Passing the ownership of raw pointers like this is one of the easiest ways to build memory issues into your code -- either leaks or double deletes.
In C++ we would not create the memory dynamically like that.
Instead you would create a temporary stack object.
You only need to create a heap object via new if you want the lifetime of the object to be greater than the call to the function. In this case you can use new in conjunction with a smart pointer (see other answers for an example).
// No need for new or memory management just do this
functionCall(className(initializers));
// This assumes you can change the functionCall to somthing like this.
functionCall(className const& param)
{
<< Do Stuff >>
}
If you want to pass a non const reference then do it like this:
calssName tmp(initializers);
functionCall(tmp);
functionCall(className& param)
{
<< Do Stuff >>
}
It is safe if the function that you are calling has acceptance-of-ownership semantics. I don't recall a time where I needed this, so I would consider it unusual.
If the function works this way, it should take its argument as a smart pointer object so that the intent is clea; i.e.
void functionCall(std::auto_ptr<className> ptr);
rather than
void functionCall(className* ptr);
This makes the transfer of ownership explicit, and the calling function will dispose of the memory pointed to by ptr when execution of the function falls out of scope.
This will work for objects created on the stack, but not a regular pointer in C++.
An auto pointer maybe able to handle it, but I haven't messed with them enough to know.
In general, no, unless you want to leak memory. In fact, in most cases, this won't work, since the result of
new T();
in C++ is a T*, not a T (in C#, new T() returns a T).
Have a look at Smart Pointers or A garbage collector for C and C++.