开发者

Will this result in a memory leak?

My C++ is pretty rusty so now that I started using it for a hobby project I g开发者_运维知识库ot to "level up"-again..

#include "stdafx.h"
#include "stdlib.h"

class a
{
public:
    void call() { printf("CALL called\n"); }
};

class b
{
public:
    b() { this->pointer = new a; }
    void call() { this->pointer->call(); }
private:
    a* pointer;
};

int _tmain(int argc, _TCHAR* argv[])
{
    b t;
    t.call();

    system("PAUSE");
    return 0;
}

Will that result in a memory leak? And how can I delete the pointers if the program decides it does not need them anymore?

Would "delete t" be enough or would that produces a memory leak too?


pointer in b is allocated but never deleted. You'll want to define a destructor for b that deletes a, otherwise you will leak the a pointed to by pointer every time a b goes out of scope:

b::~b()
{
    delete pointer;
}


Class b contains a pointer that you allocate but never free. Yes, that will result in a memory leak.

The old-fashioned way to deal with this is to delete the pointer in the destructor of b since you know it can never be used again.

The newer method is to use a "smart pointer" such as boost::shared_ptr (or std::auto_ptr if you must) rather than a plain pointer to the object.


~b() { delete pointer; }

For every new, there must be a matching delete.


Yes, it will.

You should add this function to your b class:

~b() { delete this->pointer; }


1) Yes it will result in a memory leak because a is dynamically allocated but never freed.
2) No - delete t won't suffice as t is responsible for managing/freeing it's own resources.
To fix this you need to write a destructor for b i.e

~b()
{
   delete pointer;
}

However, to be super-safe you could also make the destructor virtual
i.e.

virtual ~b()
{
   delete pointer;
}

This will ensure that the correct destructor gets called in any derived classes
HTH


You cannot delete t, that is not a pointer. You could have a method in b called "release" that deletes the pointer early if you want. In this example a looks a bit like a "pImpl" for b, i.e. it is used to implement the identical call in b.

As the other respondents have correctly stated, if b creates the pointer to a with new, its destructor must delete it but you need more than that. You need to ensure that you don't make copies of b that will also try to delete the pointer. Therefore make b non-copyable and not assignable. If they need to be copyable or assignable you must overload those to manage the pointer.


The other answers are all correct that you need to add a destructor that deletes the pointer member. I'll add that you also probably need a copy constructor and copy assignment operator that deal with that pointer properly (the Rule of Three).

Also, I'll suggest that you look into smart pointers, such as boost::shared_ptr (which will become std::shared_ptr in C++0x).


Technically there is no memory leak because the program exits after the pause completes. When the program exits, all memory allocated by it is freed.

But of course the other answers are correct. "b" should have a destructor that deletes the memory allocated by the "new".


As the answers before noted class "b" should have a destructor that deletes the memory allocated in the constructor. However, as Martin York commented above, this is not a comprehensive answer. As he noted there are issues here that you need to take care of regarding copy constructor and assignment operator but I would go even further: stop using raw pointers and start using Boost smart pointers immediately.

Class "b" rewritten to use boost::shared_ptr<>:

class b
{
public:
    b() { this->pointer.reset(new a); }
    void call() { this->pointer->call(); }
private:
    boost::shared_ptr<a> pointer;
};

Note two things:

  1. We don't have to write an explicit destructor as shared_ptr will automatically destroy the object it points to (for more information on the conditions see the documentation on it).
  2. We don't have to write an explicit copy constructor or assignment operator if shallow copy of object pointed by pointer is enough because shared_ptr again takes care of that automatically by providing its own "shallow copy" copy constructor and assignment operators.

The upcoming C++0x standard also has several smart pointers including shared_ptr. Also see scoped_ptr as well as shared_array and scoped_array in Boost. This last I find particularly useful when dealing with C APIs like Win32.


In class B you could simply create an A instance on the stack. This relieves ownership issues. In my experience if you can create a member variable on the stack then do so. Deletion is then automatic. If you can't then I suggest a 3rd party supplies a pointer to your B class. The pointer supplied is encapsulated within some kind of smart pointer.

One of the "problems" with C++ is ownership. I.e. who owns what and who should delete what. Only careful class design helps alleviate this problem and reduce memory leaks.

In your somewhat contrived example, class B owns the pointer to A as it is created in the constructor. So, in this example, class B should contain a destructor that deletes the A instance.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜