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
#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
#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