3

Afer reading this topic C++ interview preparation (Matt's answer) I've got a question about boost::shared_ptr. Is it really possible for shared_ptr to leak memory? How?

Community
  • 1
  • 1
ledokol
  • 461
  • 1
  • 4
  • 13
  • 1
    refer this : http://stackoverflow.com/questions/1826902/how-to-avoid-memory-leak-with-boostshared-ptr – Arunmu Feb 09 '11 at 05:13
  • 1
    `new boost::shared_ptr(new T()); // o noez!` – James McNellis Feb 09 '11 at 05:16
  • @James McNellis: nice example :-D – ledokol Feb 09 '11 at 05:17
  • `{ boost::shared_ptr sp(new T()); std::exit(0); } // o noez!` – James McNellis Feb 09 '11 at 05:23
  • `{ boost::shared_ptr sp(new T()); std::terminate(); }` :) – ledokol Feb 09 '11 at 05:25
  • 1
    `void f(std::shared_ptr, int);` called as `f(std::shared_ptr(new T()), (throw 0, 0)); // maybe o noez... maybe not` – James McNellis Feb 09 '11 at 05:26
  • I don't think it should count as a leak if the only reason it leaked was because someone called `exit`, *unless* the leak is visible outside the program (e.g. some state in the filesystem didn't get cleaned up). Not bothering to tear down memory-only data structures can be the difference between a speedy exit and the user twiddling their thumbs for long enough to get irritated. – zwol Feb 09 '11 at 05:39

3 Answers3

3

shared_ptr uses reference counts, and that means circular references can cause leaks. Concretely:

struct A {
    shared_ptr<A> other;
};

shared_ptr<A> foo() {
    shared_ptr<A> one(new A);
    shared_ptr<A> two(new A);
    one->other = two;
    two->other = one;
    return one;
}

the data structure returned by foo will never be deallocated without manual intervention (set either of the other pointers to NULL).

Now this is just a fact that every programmer should know; the more interesting interview conversation is what to do about it. Options include:

  • redesigning the data structure so pointer cycles are not necessary;
  • demoting at least one pointer in every cycle to a non-owning reference (a bare pointer or a weak_ptr);
  • a dedicated cycle collector;
  • as a last resort, manually NULLing out pointers at appropriate points (this breaks exception safety).
zwol
  • 135,547
  • 38
  • 252
  • 361
  • Thank you! Never had such situation, that looks quite strange, it's better to avoid cycles. – ledokol Feb 09 '11 at 05:22
  • It does make life easier to avoid cycles, but sometimes they are necessary, and sometimes avoiding them is way more work than dealing with them. – zwol Feb 09 '11 at 05:40
  • Yes, but that's a rare situation, and situation, where cycles need to use shared_ptr are rare even more. Weak_ptr looks like a good solution to that, however it would be interesting to read about dedicated cycle collectors. – ledokol Feb 09 '11 at 05:44
1

Circular references; a common problem in reference counting garbage collectors.

I suggest you read the following: http://www.codeproject.com/KB/stl/boostsmartptr.aspx#Cyclic References

hiddensunset4
  • 5,825
  • 3
  • 39
  • 61
0

shared_ptr is a reference counting mechanism. One gotcha with ref counting is you can have a circular chain of references no one else refers to. You chain will never get freed unless there's a mechanism to 'break the chain'.

seand
  • 5,168
  • 1
  • 24
  • 37