Jim Barry:
I am trying to detect circular references using the find_unreachable_objects function in sp_collector.cpp. However, it reports false positives in the simple case of one object being owned by another. To illustrate:
#define BOOST_SP_ENABLE_DEBUG_HOOKS #include
// sp_collector.cpp exported functions std::size_t find_unreachable_objects(bool report);
struct X {};
struct Y { boost::shared_ptr<X> pX;
Y() : pX(new X) {} };
int main() { boost::shared_ptr<Y> y(new Y); find_unreachable_objects(true); return 0; }
The output is as follows:
... 2 objects in m. ... 1 objects in m2. ... 1 objects in open. Unreachable object at 0036BA60, 12 bytes long.
Clearly this is incorrect as there are no circular references. Looking at the code, there is what appears to be a typo at line 124:
std::cout << "... " << m2.size() << " objects in open.\n";
should be:
std::cout << "... " << open.size() << " objects in open.\n";
But the real problem seems to be at line 121:
if(p->use_count() != i->second) open.push_back(p);
I'm not entirely sure what's going on in this section of code, but it ends up determining (incorrectly) that the "X" object is unreachable. Is there any way to get this working properly?
I admit that I don't remember what I was thinking when I wrote sp_collector.cpp in 2002-2003, but the following patch does seem to fix the problem with your example. Can you please confirm that it also works for more complicated cases? Index: sp_collector.cpp =================================================================== --- sp_collector.cpp (revision 48405) +++ sp_collector.cpp (working copy) @@ -104,6 +104,8 @@ BOOST_ASSERT(p->use_count() != 0); // there should be no inactive counts in the map + m2[ i->first ]; + scan_and_count(i->second.first, i->second.second, m, m2); } @@ -121,7 +123,7 @@ if(p->use_count() != i->second) open.push_back(p); } - std::cout << "... " << m2.size() << " objects in open.\n"; + std::cout << "... " << open.size() << " objects in open.\n"; for(open_type::iterator j = open.begin(); j != open.end(); ++j) {