Boost logo

Boost Users :

Subject: [Boost-users] memory lost using cyclic pointers (shared_ptr)
From: Peng Yu (pengyu.ut_at_[hidden])
Date: 2011-09-08 23:24:06


Hi,

I think that it is expected that shared_ptr cannot handle points that
have cyclic references. In the following example, "a" points to "b"
and "b" points to "a". There is a memory leak. I then modified it to
remove the dependence using bare pointers, then the leak is resolved.
But this is not a very satisfactory solution, as the programmer has to
know whether to use bare point or shared_ptr. For very complexity
program, it may not be possible to figure out it correctly.

Does anybody know what is the best strategy for handing cyclic pointers?

~/linux/test/cpp/library/std/tr1/shared_ptr/loop$ cat main.cpp
#include <tr1/memory>
#include <iostream>

struct B;

struct A {
  std::tr1::shared_ptr<B> p;
  void print() {
    std::cout << "A" << std::endl;
  }
};

struct B {
  std::tr1::shared_ptr<A> p;
  void print() {
    std::cout << "B" << std::endl;
  }
};

int main () {
  std::tr1::shared_ptr<A> a(new A);
  std::tr1::shared_ptr<B> b(new B);

  a->p=b;
  b->p=a;

  a->p->print();
  b->p->print();
}

~/linux/test/cpp/library/std/tr1/shared_ptr/loop$ valgrind ./main.exe
==75090== Memcheck, a memory error detector
==75090== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==75090== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==75090== Command: ./main.exe
==75090==
--75090-- ./main.exe:
--75090-- dSYM directory is missing; consider using --dsymutil=yes
B
A
==75090==
==75090== HEAP SUMMARY:
==75090== in use at exit: 4,280 bytes in 6 blocks
==75090== total heap usage: 6 allocs, 0 frees, 4,280 bytes allocated
==75090==
==75090== LEAK SUMMARY:
==75090== definitely lost: 16 bytes in 1 blocks
==75090== indirectly lost: 80 bytes in 3 blocks
==75090== possibly lost: 0 bytes in 0 blocks
==75090== still reachable: 4,184 bytes in 2 blocks
==75090== suppressed: 0 bytes in 0 blocks
==75090== Rerun with --leak-check=full to see details of leaked memory
==75090==
==75090== For counts of detected and suppressed errors, rerun with: -v
==75090== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

#removing cyclic reference by using bare pointer.

~/linux/test/cpp/library/std/tr1/shared_ptr/loop$ cat main.cpp
#include <tr1/memory>
#include <iostream>

struct B;

struct A {
  std::tr1::shared_ptr<B> p;
  void print() {
    std::cout << "A" << std::endl;
  }
};

struct B {
  std::tr1::shared_ptr<A> p;
  void print() {
    std::cout << "B" << std::endl;
  }
};

int main () {
  std::tr1::shared_ptr<A> a(new A);
  std::tr1::shared_ptr<B> b(new B);

  a->p=b;
  b->p=a;

  a->p->print();
  b->p->print();
}
~/linux/test/cpp/library/std/tr1/shared_ptr/loop$ vim main.cpp
~/linux/test/cpp/library/std/tr1/shared_ptr/loop$ make
g++ -o main.exe main.cpp
~/linux/test/cpp/library/std/tr1/shared_ptr/loop$ valgrind main.exe
valgrind: main.exe: command not found
~/linux/test/cpp/library/std/tr1/shared_ptr/loop$ valgrind ./main.exe
==75167== Memcheck, a memory error detector
==75167== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==75167== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==75167== Command: ./main.exe
==75167==
--75167-- ./main.exe:
--75167-- dSYM directory is missing; consider using --dsymutil=yes
B
A
==75167==
==75167== HEAP SUMMARY:
==75167== in use at exit: 4,184 bytes in 2 blocks
==75167== total heap usage: 6 allocs, 4 frees, 4,272 bytes allocated
==75167==
==75167== LEAK SUMMARY:
==75167== definitely lost: 0 bytes in 0 blocks
==75167== indirectly lost: 0 bytes in 0 blocks
==75167== possibly lost: 0 bytes in 0 blocks
==75167== still reachable: 4,184 bytes in 2 blocks
==75167== suppressed: 0 bytes in 0 blocks
==75167== Rerun with --leak-check=full to see details of leaked memory
==75167==
==75167== For counts of detected and suppressed errors, rerun with: -v
==75167== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

-- 
Regards,
Peng

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net