Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/C++/Front End/Destructors    [ Add a report in this area ]  
Report #:  91256   Status: Closed
Failure to destruct member shared_ptr after an exception is thrown
Project:  C++Builder Build #:  15.0.3953.35171
Version:    15.1 Submitted By:   Øystein Svinning
Report Type:  Crash / Data loss / Total failure Date Reported:  2/1/2011 5:26:09 AM
Severity:    Serious / Highly visible problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   281763
Resolution: Retest (Resolution Comments) Resolved in Build: : 16.0.4239.42776
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 10
Description
Class Bar has  a member that is a boost::shared_ptr for an object of class Foo. Foo has a defined constructor and destructor.

class Bar
{
  public:
    Bar(const boost::shared_ptr<Foo>& input)
      FooPtr(input) {}

  private:
    std::string s0;
    std::string s1;
    boost::shared_ptr<Foo> FooPtr;
};

If the following code is executed the shared count of ptr will be 2 inside the catch block, it should be reduced to 1. Consecuently the object Foo pointed to by ptr will not be destructed when ptr goes out of scope.

boost::shared_ptr<Foo> ptr(new Foo());

try
{
  Bar barObj(ptr);
  {
    Bar barObjLocal(ptr);
  }

  throw 1;
}
catch (int i)
{
  // use_count of ptr is 2
}
Steps to Reproduce:
#include <iostream>
#include <boost/shared_ptr.hpp>

// Class with no contents. Constructor and destructor provide output to cout
class Foo
{
  public:
    Foo()
    {
      std::cout << "Constructing Foo" << std::endl;
    }
    ~Foo()
    {
      std::cout << "Destructing Foo" << std::endl;
    }
};
//---------------------------------------------------------------------------

// Class containing two strings and a pointer to a Foo object. Constructor sets
// the member Foo pointer. Destructor is not implemented.
class Bar
{
  public:
    Bar(const boost::shared_ptr<Foo>& input) : FooPtr(input) {}
//    ~Bar() {}

  private:
    std::string s0;
    std::string s1;
    boost::shared_ptr<Foo> FooPtr;
};
//---------------------------------------------------------------------------


int main(int argc, const char* argv[])
{
  boost::shared_ptr<Foo> ptr(new Foo());

  try
  {
    Bar barObj(ptr);
    {
      Bar barObjLocal(ptr);
    }

    throw 1;
  }
  catch (int i)
  {
    std::cout << "use_count for ptr in catch: " << ptr.use_count()
              << ", should be 1" << std::endl;
  }



  return 0;
}
//---------------------------------------------------------------------------
Workarounds
* Add an empty destructor to the class Bar in the example.
* Move FooPtr member of class Bar to the top of the list of private members in class Bar
* Do not put barObjLocal in a seperate scope inside the try block
Attachment
None
Comments

None

Server Response from: ETNACODE01