Sequential new & delete - c++

In continuation to my previous question, I would like to ask the following :
Given a C++ function having a new statement in it but not returning anything explicitly (i.e. with a return statement), should it also always have a delete?
If no, could you please give me an example.

It doesn't have to explicitly return the newly-created object, but it should pass it to something else in some way. Possible scenarios include:
In a member function, create an object and assign it to a field of the containing object.
Example:
class Foo {
private:
Baz* baz;
public:
Foo() : baz(0) { }
void create_bar() { baz = new Baz(); }
~Foo() { delete baz; }
};
Passing the new object to something else.
Examples:
void foo() {
// assuming bar lives in the global scope
bar.baz = new Baz();
}
void foo2(Bar& bar) {
bar.baz = new Baz();
// or, better:
bar.setBaz(new Baz());
}
Using some kind of garbage-collecting pointer type.
Example:
std::auto_ptr<Baz> foo() {
return new Baz();
}
Passing the pointer into another function that does something with it and then deletes it.
Example:
void foo(Bar* bar) {
bar->dostuff();
delete bar;
}
void baz() {
Bar* bar = new Bar();
foo(bar);
}

The rule with new is very simple: the pointer returned by new must be deleted at some point by someone, somewhere in the code. If the pointer returned by new is lost, forgotten, or discarded, then you have a memory leak, and that is bad.
Therefore, if you new up some memory and return without storing it anywhere permanently, then you have leaked memory. Therefore, if you aren't going to delete it, then the pointer must be either stored in some kind of long-term storage (member of a class, static variable, etc) or it must be returned so that someone else can delete it.
Alternatively, you can just use a boost::shared_ptr and stop caring about (most of) this.

If you are allocating memory with new in a function, and that memory isn't accessible outside the function (or static), then it would need to be freed before the function exists. In this case, i'd recommend using std::auto_ptr or boost::scoped_ptr, as it will call delete for you when the function exits. Even if exceptions are thrown.

No, if the purpose of the function is to instantiate some data and hand it over to some other object. A (hypothetical) example from the games industry:
void AddProjectileAtPoint(int x, int y)
{
Projectile *p = new Projectile(x, y);
mProjectileManager->Add(p); //"mProjectileManager"'s job is to hold all projectiles and update them every frame...
}
In this case the purpose explicitly is to create a new object representing some data and store it somewhere for later use.
Obviously, there will need to be a matching delete at some point, but not within the function where the new occurs. This is fine as long as there is a clearly defined procedure for passing responsibility for managing the new'd memory to some other component.
In this case the structure is that the "Projectile Manager" takes responsibility for all projectiles it is given, will keep them alive for as long as is required and will clean-up the memory when it is appropriate.

If the function creates a resource using new and doesn't pass a pointer to that resource back to anything then yes it must delete the resource otherwise it will never get cleaned up, causing a memory leak.

Not necessarily, if it's allocating a static object (e.g. to implement a Singleton pattern).

No, not necessarily. You might have stored a pointer to the dynamically-allocated object somewhere else. e.g. for some class A:
A* ptr = NULL;
void foo() {
ptr = new A();
}
You should have a delete ptr somewhere, but it doesn't have to be in foo().
On the other hand, if you didn't store it anywhere else:
void foo() {
A* ptr = new A();
}
Then, yes, this is a memory leak. You can never get back to that pointer to do delete ptr!
Note that it's better to use some "smart pointer" implementation like shared_ptr or unique_ptr to handle this stuff for you.

Related

Delete pointer and object

How do I delete a pointer and the object it's pointing to?
Will the code below delete the object?
Object *apple;
apple = new Object();
delete apple;
And what happens if the pointer is not deleted, and gets out of scope?
Object *apple;
apple = new Object();
This might be a very basic question, but I'm coming from Java.
Your first code snippet does indeed delete the object. The pointer itself is a local variable allocated on the stack. It will be deallocated as soon as it goes out of scope.
That brings up the second point--if the pointer goes out of scope before you deallocate the object you allocated on the heap, you will never be able to deallocate it, and will have a memory leak.
Hope this helps.
Hello and welcome to C++ land! You will love how much you hate it (or something like that). C++, while appearing to be similar to java in untrained eyes might look similar, is actually quite different semantically. Lets see how these semantics play out in c++ in regards to your question. First lets take a class:
class Foo {
public:
Foo() { std::cout << "In constructor\n"; }
~Foo() { std::cout << "In destructor\n"; }
};
Foo here is just a representative of any class you might want to use. Lets see what happens when we create and play with a normal Foo object:
{
Foo bar;
do_stuff(bar);
}
If we were to run code that looked like this, we would see:
In constructor
In destructor
This is because, when an object is created, it is constructed using the constructor. When it goes out of scope, the destructor is called (~Foo in our code) which deconstructs (or destroys) the object. This is actually a fairly common and powerful feature in C++ (known as RAII, as opposed to other forms of returning memory to the system, such as Garbage Collection). Armed with this new knowledge, lets see what happens when we play with a pointer to Foo:
{
Foo *bar = new Foo();
some_more_stuff(bar);
}
What happens here is we would see:
In constructor
This is because of how pointers are allocated versus how variables are allocated. The way pointers are allocated, they don't actually go out of scope normally, but their contents do. This is known as a dangling pointer. For a better example, take a look at this:
#include <iostream>
int* get_int() {
int qux = 42;
int *foo = &qux;
return foo;
}
int main() {
int *qazal = get_int();
std::cout << *qazal;
}
Thanks to modern operating systems, this memory will still be returned when the program finishes, but not during the running of the program. If we were to delete the pointer (in the same scope it was created) via delete, then that memory will actually be returned to the operating system at that time.
When you call delete on a pointer it frees the memory of the thing pointed to. In other words you don't need to free the memory that makes up the pointer variable, just the thing that is pointed to. So your code:
Object *apple;
apple = new Object();
delete apple;
correctly deletes the object and there will be no memory leak.
If you don't call delete and the variable goes out of scope then you'll have a memory leak. These can be difficult to track down, so it's advisable to use a smart pointer class.
Operator delete deletes an object pointed to by the pointer that previously was allocated with operator new.
The pointer itself is not changed and even will have the same value as before the calling the operator. However its value becomes invalid after deleteing the object.
If the pointer itself is a local variable it will be destroyed after the control leaves the declaration region of the pointer.
If the pointer has the static storage duration then it will be destroyed when the program finishes its execution.
Take into account that you can use smart pointers instead of raw pointers.
For example
std::unique_ptr<Object> apple( new Object() );
in this case you need not to call delete It is the smart pointer that will do all the work itself.
Will the code below delete the object?
Yes, it will. But the pointer isn't deleted and accidentally using the pointer after deletion will lead to error.
And what happens if the pointer is not deleted, and gets out of scope?
Memory leak will happen.

C++ memory deallocation after return

I have this question regarding memory allocation and deallocation in c++.
Here is the situation:
I have a method foo which allocates memory and then returns that object:
Object foo () {
Object *a = new Object();
// Do something with this object...
return *a;
}
and another method which uses this returned object:
void bar () {
Object a = foo();
// Do something..
}
And my question is, at which point should i deallocate the memory I have allocated? When i return from the method foo, does the method bar get a copy of that object on its stack, or does it get access to that one object somewhere in memory?
Thanks!
Bart
You can't deallocate that object. It's lost. It's a memory leak. You never should have (dynamically) allocated it in the first place. Your code should have looked like this:
Object foo () {
Object a;
// Do something with this object...
return a;
}
When i return from the method foo, does the method bar get a copy of
that object on its stack, or does it get access to that one object
somewhere in memory?
It's a copy of the still existing inaccessible object.
Youre leaking memory because you are not returning the object you allocated, but a copy of it.
The easiest solution is to not use new at all
Object foo () {
Object a;
return a;
}
If you really need the object on the heap, e.g. if it's a polymorphic object and your're returning a pointer to the base class it would look like
Base* foo () {
Base *a = new Derived();
return a;
}
But this code is far from good. It's not exception save which can lead to memory leaks as well. Therefore you should almost always wrap a new with a smart pointer like std::unique_ptr(only c++11), std::auto_ptr or boost::shared_ptr.
std::unique_ptr<Base> foo () {
std::unique_ptr<Base> a(new Derived();
return a;
}
Allocating memory with new tells the compiler: "don't worry, I know what I'm doing: this object will be controlled by me". That means, the compiler will, indeed, not worry about it and you are put in charge. The best solution is: don't do it unless you really know what you are doing. Note, that I'm pretty sure that I know what I'm doing and still I normally don't use new because there is no need!
In your example, you want to use
Object foo() {
Object a;
// do something
return a;
}
Conceptually, the object is created on the stack and copied when it is returned. After the copy is done, the local object is destroyed. In practice, this is rarely what really happens: since the local object is destroyed right after it is copied, the compiler is given freedom to do what you normally want and that is: the object a isn't copied or destroyed but actually returned directly. However, this should yield the same result (if it does not, your class is broken somewhere).
In this example you can't. Since the caller function will never know where (or even aware) a dynamically object was created.
If you were to use references (or pointers) then it would be the callers responsibility to release it when finished using it.

Pointers inside classes methods / functions

I'd like to know how C++ is dealing with memory of "objects" created by pointer inside class methods or functions.
For example method of class Example
void Example::methodExample()
{
ExampleObject *pointer = new ExampleObject("image.jpg");
}
Should i somehow delete this or it's automatically removed?
Sorry if my question is stupid but i am beginner : P
You have two options.
If you use a raw pointer, as you are using in your example, you must manually delete objects that were created with new.
If you don't, you have created a memory leak.
void Example::methodExample()
{
ExampleObject *pointer = new ExampleObject("image.jpg");
// Stuff
delete pointer;
}
Or you may use smart pointers, such as boost::scoped_ptr or C++11's std::unique_ptr.
These objects will automatically delete their pointed-to contents when they are deleted.
Some (like me) will say that this approach is preferred, because your ExampleObject will be correctly deleted even if an exception is thrown and the end of the function isn't reached.
void Example::methodExample()
{
boost::scoped_ptr<ExampleObject> pointer( new ExampleObject("image.jpg") );
// Stuff
}
You shouldn't be doing your own memory management at all in modern C++. Use unique_ptr or scoped_ptr, which will automatically delete the pointer when they go out of scope.
I think the appriate approach for dealing with raw pointers (as you exemplified) is to store the pointer as a member of the class. Then you can allocate memory for this pointer in any method you would like and leave to free the memory on the destructor of the class. Something along these lines:
class Example
{
public:
Example();
~Example();
void methodExample();
private:
ExampleObject* pointer;
};
void Example::Example()
: pointer(NULL)
{
}
void Example::~Example()
{
if (pointer) // release memory only if it was allocated
delete pointer;
}
void Example::methodExample()
{
pointer = new ExampleObject("image.jpg");
// add a safety check to verify if the allocation was successful
}
If your object is scoped within the function then your correct construct is not to use a pointer at all but use an automatic object, which should be created like this.
ExampleObject example("image.jpg");
You might use a pointer where you are, for example, in an if construct at the time, where the else condition would not construct an object, and then you want to use the object later.
In such a case use an automatic pointer object, preferably unique_ptr if available, boost::scoped_ptr if not, but even the deprecated std::auto_ptr is better than a raw one. For example:
std::unique_ptr<ExampleObject> example;
if( usingAnExample )
{
example.reset( new ExampleObject("image.jpg") );
}
else
{
// do stuff
}
// I still need example here if it was created
You should
delete pointer;
when you no longer need it. The pointer goes out of scope at the end of the function but the memory is still allocated on the heap.

C++ delete an object

I am not experienced in handling of the memory in a C++ program, so I would like a piece of advice in that case:
I want to create a new Object in a function in a class which is essential till the end of the program. As far as I am concerned, if I use the operator new, I should sometimes delete it. Taking into account that it must be initialized inside a class, when and how must I finally delete it?
I suggest the smart pointer idiom
#include <memory>
struct X
{
void foo() { }
};
std::share_ptr<X> makeX() // could also be a class member of course
{
return std::make_shared<X>();
}
int main()
{
std::share_ptr<X> stayaround = makeX();
// can just be used like an ordinary pointer:
stayaround->foo();
// auto-deletes <sup>1</sup>
}
If the pointer is truly a static variable, you can substitute a unique_ptr (which works similarly, but passes ownership on assignment; this means that the pointer doesn't have to keep a reference count)
Note To learn more about C++ smart pointers in general, see smart pointers (boost) explained
Note If you don't have the TR1/C++0x support for this, you can just use Boost Smartpointer
1 unless you are leaking copies of the shared_ptr itself; that would be some strange use of smart pointers previously unseen :)
Edit: Using some sort of smart pointer is often a good idea, but I believe it is still essential to have a solid understanding of manual memory management in C++.
If you want an object in a class to persist until the end of the program, you can simply make it a member variable. From what you've said, there's nothing to suggest you need to use new or delete here, just make it an automatic variable. If you did want to use new and delete for practice, you should read up on constructors and destructors for a class (you can and will use new and delete outside of classes, but I'm trying to keep this relevant to your question). Here's one I prepared earlier:
class Foo
{
public:
Foo(); // Default constructor.
~Foo(); // Destructor.
private:
int *member;
}
Foo::Foo() // Default constructor definition.
{
member = new int; // Creating a new int on the heap.
}
Foo::~Foo() // Destructor.
{
delete member; // Free up the memory that was allocated in the constructor.
}
This is a simple example, but it will hopefully help you out. Note that the variable will only persist as long as the object is alive. If the object is destroyed or goes out of scope, the destructor will be called and the memory will be freed.
You can use the smart pointer as suggested by Sehe or you can create a static object in the function and return a reference to it. You need not explictly delete the object, when the process terminates the object will be deleted. Like:
struct X {};
X& makeX() // could also be a class member of course
{
static X x;
return x;
}
int main()
{
X& stayaround = makeX();
}
On most operating systems (in particular Linux), if you allocate an object pointer with new Object, and don't bother delete-ing because you'll need it till the program ends, no harm is really done. There is some memory leak inside your program (you can use valgrind to hunt such leaks) but the kernel will release all the memory used by a process when it has ended.
A better alternative is to have a singleton class for the application data, like e.g. QApplication in Qt, ahd construct a single instance in that class early in your main, and have that class contain a smart or dumb pointer to your Object. The destructor should delete that object.

c++ must delete a references?

in the following code:
class x
{
private:
someRef& m_ref;
public:
x(someRef& someRef):m_ref(someRef)
{
}
do I need to do:
~x()
{
delete m_ref;
}
which by the way doesnt work without getting the pointer...
basically I'm asking: Do I need to call a destructor on a reference member?
No.
You only need to delete an object if you own it. If you were passed a reference, it means that someone else owns it, thus it's unnecessary and thankfully the language prevents it.
I don't think one actually strictly speaking ever deletes even pointers. What you delete are dynamically allocated objects (or arrays of objects) that the pointer is a handle for. If the object originates from a call to new and it is the responsibility of this class to clean up after this object, then you call delete.
It is technically possible that a reference might be referring to a dynamically allocated object:
int main()
{
//in principle a reference can also refer to a dynamically allocated object
x var(*new someRef);
}
//and if that is the intended usage:
x::~x()
{
delete &m_ref;
}
However, this would be incredibly bad style. By convention, the "owning" handle of a dynamically allocated object should not be a reference.
No. You can only delete pointers, not references, and even then you must only delete objects that you allocated using the new operator. And then you must be sure to delete them only once. Here is the case in which you would need to use delete in your destructor:
class x
{
private:
someObj* m_ptr;
public:
x():m_ptr(new someObj())
{
}
~x()
{
delete m_ptr;
}
But in general it's best to avoid even this and use smart pointers instead.
I want to clarify some misconceptions you seem to have that are beyond the intent of your question:
When a class's destructor is called all of it's members' destructors get called as well.
Calling delete is not the same as calling the destructor. delete explicitly calls the destructor and also calls operator delete at the objects location, it is a 2 part thing.
For a small bit of extra clarification I want to offer the following:
int *pi = new int;
//int& ir = pi; // can't do
// this a reference to the pointer but it is an error
// because or the type difference int& vs int* and
// static_cast won't help. reinterpret_cast would allow
// the assignment to take place but not help the 'delete ir'
int& ir = *pi; // this is OK - a reference to what the pointer points to.
// In other words, the the address of the int on the heap.
//delete ir; // can't do, it is a reference and you can't delete non-pointers.
delete &ir; // this works but it is still not "deleting a reference".
// The reference 'ir' is another name for the heap-based int.
// So, &ir is the address of that int, essentially a pointer.
// It is a pointer that is being used by delete, not a reference.