I know that I can't get a reference of a local var. such as:
int& func1()
{
int i;
i = 1;
return i;
}
And I know that this is correct, but I have to delete it after calling func2()
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int *p = func2();
cout << *p << endl;
delete p;
return 0;
}
If the function is like this:
MyClass MyFunction()
{
return new MyClass;
}
MyClass's whole definition is:
class MyClass
{
public:
MyClass() : num(1){}
MyClass(MyClass*) : num(10){}
int num;
};
Will this cause memory leak?
How should I avoid it?
the function returns an object not a pointer, so how can I delete it?
PS: the code comes from the book "Ruminations on C++" Chapter 10.
the original code is:
Picture frame(const Pictrue& pic)
{
// Picture has a constructor Picture(*P_Node)
// Frame_Pic derives from P_Node
// So the constructor Picture(*P_Node) will implicitly convert Frame_Pic to Picture.
return new Frame_Pic(pic);
}
MyClass MyFunction()
{
return new MyClass;
}
This is actually wrong.you are returning a pointer .
so it should be
MyClass* MyFunction()
if your function is as i mentioned above and if you are not deleting it after using it.it will leak memory.
How should I avoid it? the function returns an object not a pointer, so how can I delete it?
that is a compilation error.so the point of deleting it will not rise
If you delete the pointer returned from the funciton there is no memory leak. However this is error prone since it means that every client of the function must know that it should delete the return value. It's much better style to use a smart pointer (either shared_ptr or unique_ptr according to semantics).
The same goes to the Picture example. If this object correctly manages its resources (i.e. deletes in the destructor and has a good copy constructor and operator= (in accordance with the Rule of Three), then there is no memory leak.
With your updated MyClass that has the pointer constructor, I suppose you should write:
MyClass MyFunction() {
MyClass *ptr = new MyClass;
MyClass retval(ptr);
delete ptr; // the dynamically-allocated object isn't needed any more
return retval;
}
That happens to be exception-safe, since the constructor of MyClass can't throw, but as a general rule you really shouldn't ever call new without putting the result straight into a smart pointer:
MyClass MyFunction() {
std::unique_ptr<MyClass>(new MyClass);
return MyClass(ptr);
}
It's a fairly absurd situation anyway - if you're going to return by value, there's no reason to call new at all:
MyClass MyFunction() {
MyClass tmpvalue;
return &tmpvalue; // doesn't actually return the pointer, just an object
// constructed from it
}
And since the value of the pointer isn't even used by the pointer constructor, you could just as well write:
MyClass MyFunction() {
return 0; // returns an object constructed from a null pointer
}
In the original code your quote from the book, I guess that the class Picture has a data member of type P_Node*, in which it stores the pointer value, and calls delete on that pointer in its destructor. Hopefully the author also does something about the copy constructor and copy assignment operator of Picture, to prevent a double-free after the copy. I don't have the book, so I can't check my guess, but the code for Picture should show how it's done.
[Edit: oh, that's one of the books by Koenig and Moo. They are (more than) competent, so pretty certainly their Picture class handles the resource correctly. If it doesn't, it's because it's a deliberate example of Doing It Wrong.]
It's the same as your "func2" example. who ever call "frame" need to free the returning Picture in the end.
MyClass MyFunction()
{
return new MyClass;
}
is incorrect, because operator new returns a pointer to MyClass, but your function returns MyClass, not MyClass*
A simple check would be this:
If you're using N number of new in your program, then you've to use N number of compatible1 delete in your program to avoid memory leak2.
So are you doing that? Yes, in the first case (in which you're doing new int) you're doint that. There is no memory leak.
And rest of the post isn't clear enough to me!
1. By compatible delete, I mean if you're using new in the form of ptr = new T[M], then the compatible delete should be of the form of delete []ptr. Similarly, delete ptr is compatible with ptr = new T.
2. Of course, if you're using some smart pointers, then you don't have to use delete explictly.
Related
I've a simply question.
I have been looking for the answer but I might not found the correct tags or words to find the solution...
The question is, as the title says: Do local variables (which have reserved memory) need to be freed? I meant, for example, if I've got the following function:
myClass* myFunction(){
myClass* A = new myClass;
return A;
}
In case of "yes", where Should I call "delete"? both before and after "return" are nonsense...
Am I right?
Don't use new unless you need to.
This avoids new, and so doesn't need deleting
myClass myFunction(){
myClass A;
return A;
}
If you think you need pointers, consider using smart pointers.
If you want the excitement of raw pointers, this function returns a raw pointer to the caller, and they must delete it when they are done.
myClass * myFunction(){
myClass * A = new myClass;
return A;
}
myClass * thing = myFunction();
//stuff, that might throw an exception, so watch it
// smart pointers FTW
delete thing;
Assuming that your type is defined something like this:
class myClass { /* ... */ };
Your example is not proper C++ (unless you have a myClass* conversion constructor, which you probably don't).
You do not have to new an object that sits on automatic memory:
myClass myFunction(){
myClass a;
return a;
}
When newing an object on dynamic memory, you can then put it into a pointer variable in automatic memory:
myClass* myFunction(){
myClass* a = new myClass;
return a;
}
Here, a might leak, if it isn't freed by the caller.
Presumably, unless you're doing some interesting operator overloading, you mean to assign new myClass to a pointer and return the pointer
myClass *myFunction(){
myClass *A = new myClass;
return A;
}
If that is the case, then yes, you will have to delete it at some point. It will be up to the caller of this function to keep the pointer and delete it when appropriate.
Alternatively you can use smartpointers.
Use shared_ptr instead of raw pointers.
std::shared_ptr<myClass> myFunction()
{
std::shared_ptr<myClass> A = std::make_shared<myClass>(constructor parameters, if any);
return A;
}
void f()
{
std::shared_ptr<myClass> A = myFunction();
}
This will emulate Java-style garbage collection.
To avoid keep having to use -> and instead work directly with the object, is it acceptable practice to do:
obj x = *(new obj(...));
...
delete &obj;
This is not just poor practice, but:
Leaking memory (most likely, unless you are using some pattern that is not visible from the code you provided), since obj will store a copy of the original object created by the new expression, and the pointer to that object returned by new is lost;
Most importantly, undefined behavior, since you are passing to delete a pointer to an object that was not allocated with new. Per paragraph 5.3.5/2 of the C++11 Standard:
[...] In the first alternative (delete object), the value of the operand of delete may be a null pointer
value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8)
representing a base class of such an object (Clause 10). If not, the behavior is undefined.
No, and in fact this leads to a leak. x is copy initialized, so the original object pointed to by new obj is lost.
Just use
obj x(...);
No need for dynamic allocation. Or
obj x = obj(...);
if you must (doubt it).
Certainly not; that copies the dynamic object to an automatic variable, loses the only pointer to it, and then attempts to delete the automatic copy. You've got a memory leak and an invalid deletion.
Much better would be to use an automatic variable in the first place:
obj x(...);
...
// no need to delete anything
or, if it really must be dynamic for some reason (because it's too big for the stack, or you don't always want to destroy it here), then use a smart pointer, and a reference if you really don't like ->
std::unique_ptr<obj> p(new obj(...));
obj & x = *p;
...
// still no need to delete anything
Changing your x into a reference would be valid (as long as you're careful that exceptions, early function returns, etc. won't cause a leak), but would cause howls of confusion among anyone unfortunate enough to have to maintain it.
You cannot delete your object properly if you do it like that.
Implicitly you do the following.
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A v(*p);
//...
delete &v; // &v != p and v is not constructed via new!
return 0;
}
If you want to work with an object-like-syntax you can bind a reference to the object.
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A & r = *p;
int i = r.test();
delete p;
return 0;
}
If you delete your object through the same pointer, there will be no leak.
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.
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.
Say for example i have the following code (pure example):
class a {
int * p;
public:
a() {
p = new int;
}
~a() {
delete p;
}
};
a * returnnew() {
a retval;
return(&retval);
}
int main() {
a * foo = returnnew();
return 0;
}
In returnnew(), would retval be destructed after the return of the function (when retval goes out of scope)? Or would it disable automatic destruction after i returned the address and i would be able to say delete foo; at the end of main()? Or, in a similar vein (pseudocode):
void foo(void* arg) {
bar = (a*)arg;
//do stuff
exit_thread();
}
int main() {
while(true) {
a asdf;
create_thread(foo, (void*)&asdf);
}
return 0;
}
where would the destructor go? where would i have to say delete? or is this undefined behavior? Would the only possible solution be to use the STL referenced-counted pointers? how would this be implemented?
Thank you- i've used C++ for a while but never quite been in this type of situation, and don't want to create memory leaks.
For a stack created object, the destructor is automatically called when the object goes out of scope.
For an object created on the heap, the memory will be freed only when you explicitly call delete.
Whether you return the address of a stack created object from a function or not does not matter. The destructor will still be called when the item goes out of scope.
So for your code example:
a * returnnew()
{
a retval;
return(&retval);
}
a's destructor is called before the code jumps back to the code that calls returnnew(). You return the address of that object, but that address is pointing to a place in memory that no longer belongs to you.
Where would i have to say delete?
You only use delete when you used new
You only use delete[] if you used new[]
or is this undefined behavior?
What you do with the address of memory that doesn't belong to you will be undefined behavior. It is not correct code though.
Would the only possible solution be to use the STL referenced-counted pointers?
You could return the object by value, or you could create a new object on the heap. You can also pass in the object to the function via a parameter and ask the function to change it.
how would this be implemented?
//Shows how to fill an object's value by reference
void fillA(a& mya)
{
mya.var = 3;
}
//Shows how to return a value on the heap
a* returnNewA()
{
//Caller is responsible for deleting the returned pointer.
return new a();
}
//Shows how to return by value, memory should not be freed, copy will be returned
a returnA()
{
return a();
}
a * returnnew() {
a retval;
return(&retval);
}
Here, retval has automatic storage duration, which means that the language will automatically destruct it when it goes out of scope. The address you've returned refers to an object that no longer exists, and trying to use the return value will be an error.
When you want an object's lifetime to be controlled by you, you have to use the new operator to create it.
a* returnnew()
{
a* retval = new a();
return retval;
}
Here, you now have complete control over the lifetime of this a. It will live until you explicitly delete it, or your program ends.
You could also come up with meaningful copy semantics for your a class, and return it by value, in which case your caller would get his own copy, distinct from the original. Then, your caller doesn't care when the original goes away.
class a
{
int * p;
public:
a(a const& rhs)
{
p = new int(rhs.p)
}
a()
{
p = new int;
}
~a()
{
delete p;
}
};
Now, you can construct a fresh a as a copy of an existing a. So your function could then return an a by value, like so:
a returnnew()
{
a retval;
return retval;
}
Here retval's lifetime will end when the function returns, and it will be destructed automatically by the language, and no resources will be leaked. And your caller will have his own copy, with its own lifetime.
In my experience, most classes should have sensible copy semantics, and you should not be afraid to pass and return them by value. It's just simpler that way, and you'll avoid dangling pointer problems.
One of C++'s biggest strengths is the way that destructors are automatically called by the language when automatic storage duration objects go out of scope. If you ensure that every resource in your program is owned by such an object, you'll have a much harder time leaking resources.
As a general rule the easiest way to avoid memory leaks in C++ is to avoid using new and delete as much as possible.
If you must have a pointer to something use a smart pointer (such as a boost scoped_ptr or shared_ptr). This way you can still have your object on the heap, but it's deconstructor will be called when the smart pointer goes out of scope. Otherwise trying to be sure that you call delete in every case can be a headache and cause a lot of extra code.
+1 to Brian's answer, just want to add a comment about the threading aspect.
Your code to create a thread is going to destroy the asdf object that you passed to the thread function regardless of the child, because asdf is on the parent stack. Either create asdf on the heap, or pass by value. Otherwise, the parent will destroy asdf, and leave your child thread pointing to a bad address on the parent's stack. Not good in any case, destructors or no destructors. The only way you'd safely pass asdf to a function in a thread would be if you created the thread first, and asdf was a stack object in ITS stack, not the parent stack.
void foo(void* arg) {
bar = (a*)arg; // child has reference to a parent stack address!
//do stuff
exit_thread();
}
int main() {
while(true) {
a asdf; // parent stack
create_thread(foo, (void*)&asdf); // parent and child diverge here, asdf auto-destroyed
}
return 0;
}
In the case of the following code:
void foo(void* arg) {
bar = (a*)arg;
//do stuff
exit_thread();
}
int main() {
while(true) {
a asdf;
create_thread(foo, (void*)&asdf);
}
return 0;
}
The destructor is called at the closing brace of the while loop. This means it will be called every iteration of the loop (and the will be constructed again for the next iteration).
As a useful tool in exploring the nuances of constructors and destructors and scopes, consider using the following class to help you answer these questions by yourself in the future:
class trace {
private:
std::string msg_;
public:
explicit trace(const std::string &msg) : msg_(msg) {
std::cerr << "Constructing: " << msg_ << std::endl;
}
~trace() {
std::cerr << "Destructing: " << msg_ << std::endl;
}
};
Use it thusly:
trace glb("global");
main() {
trace t1("top of main");
for(int i = 0; i < 10; ++i)
{
trace t2("inside for");
}
return 0;
}
The results may surprise you.
returnnew() will destroy the variable upon return because you're returning a pointer to a local variable. If you want to return retval from there, allocate it dinamically, eg:
a * returnnew() {
a * retval = new a;
return retval;
}
Or just:
a * returnnew() {
return new a;
}
Dynamic allocated memory has no scope, and thus won't be deallocated until you say so, by means of a delete/delete[]/free, or until the program exits (and few other cases not related to the question). Before anyone comments here, my "until you say so" also includes shared/smart/etc pointer behaviour.
As for your second code & questions, if you are allocating the variable outside the thread, but ONLY using it from inside, you can just make the thread deallocate (delete) it when it's no longer needed. However, if you plan to access the variable from multiple points, and you can't guess when you're safe to destroy it, surely, use a smart or shared pointer.