f



Destructor called twice

#include <iostream>
#include <vector>

class MyClass2 {
public:

  MyClass2() {
    std::cout << "MyClass2: Constructor." << std::endl;
  }

  ~MyClass2() {
    std::cout << "MyClass2: Destructor." << std::endl;
  }

};

class MyClass1 {
public:

  MyClass1(MyClass2 * m) {  // new pointer to m
    std::cout << "MyClass1: Constructor." << std::endl;
    mc2 = m;
  }

  ~MyClass1() {
    std::cout << "MyClass1: Destructor." << std::endl;
    delete mc2;
  }

private:
  MyClass2* mc2;
};

int main () {

  std::vector<MyClass1> v;
  v.push_back( MyClass1(new MyClass2) );

  std::cout << "End of main." << std::endl;
}

-----------------------------------------------------------------

Hello!

The code pasted above will call the destructor for the same object twice. My
guess is that when calling v.push_back, a temporary variable of the argument
is copied to push_back. At the end of push_back the temporary variable is
destroyed together with  the object it represents. Then again, at the end of
the main function, the element in the vector is destroyed, which will lead
to the same object being destroyed again.

I was wondering if it's possible to fix this problem without having to
change the code in the main function? Any ideas are very much appreciated.

Thanks in advance!


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
teztingit
5/11/2015 7:16:50 AM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

11 Replies
633 Views

Similar Articles

[PageSpeed] 10

On 11/05/2015 14:16, teztingit@googlemail.com wrote:
>
> #include <iostream>
> #include <vector>
>
> class MyClass2 {
> public:
>
>    MyClass2() {
>      std::cout << "MyClass2: Constructor." << std::endl;
>    }
>
>    ~MyClass2() {
>      std::cout << "MyClass2: Destructor." << std::endl;
>    }
>
> };
>
> class MyClass1 {
> public:
>
>    MyClass1(MyClass2 * m) {  // new pointer to m
>      std::cout << "MyClass1: Constructor." << std::endl;
>      mc2 = m;
>    }
>
>    ~MyClass1() {
>      std::cout << "MyClass1: Destructor." << std::endl;
>      delete mc2;
>    }
>
> private:
>    MyClass2* mc2;
> };
>
> int main () {
>
>    std::vector<MyClass1> v;
>    v.push_back( MyClass1(new MyClass2) );
>
>    std::cout << "End of main." << std::endl;
> }
>
> -----------------------------------------------------------------
>
> Hello!
>
> The code pasted above will call the destructor for the same object twice.
My
> guess is that when calling v.push_back, a temporary variable of the
argument
> is copied to push_back. At the end of push_back the temporary variable is
> destroyed together with  the object it represents. Then again, at the end
of
> the main function, the element in the vector is destroyed, which will lead
> to the same object being destroyed again.
>
> I was wondering if it's possible to fix this problem without having to
> change the code in the main function? Any ideas are very much appreciated.
>
> Thanks in advance!
>
>
But it isn't the same object, copies and clones are objects in their own 
right.
In order to push_back and object you need one, however in order to add 
an object to a vector you need to construct it in the vector's memory 
space. If you want to avoid two objects and therefore two destructor 
calls you need to construct the object in place. This might be possible 
if the vector has any spare capacity but sometimes that will not be the 
case.
Note that this would not be a problem if you were using a std::list

Francis


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Francis
5/11/2015 11:54:21 AM
On Monday, 11 May 2015 13:20:09 UTC+1, goforgit  wrote:
> #include <iostream>
> #include <vector>
> 
> class MyClass2 {
> public:
> 
>   MyClass2() {
>     std::cout << "MyClass2: Constructor." << std::endl;
>   }
> 
>   ~MyClass2() {
>     std::cout << "MyClass2: Destructor." << std::endl;
>   }
> 
> };
> 
> class MyClass1 {
> public:
> 
>   MyClass1(MyClass2 * m) {  // new pointer to m
>     std::cout << "MyClass1: Constructor." << std::endl;
>     mc2 = m;
>   }
> 
>   ~MyClass1() {
>     std::cout << "MyClass1: Destructor." << std::endl;
>     delete mc2;
>   }
> 
> private:
>   MyClass2* mc2;
> };
> 
> int main () {
> 
>   std::vector<MyClass1> v;
>   v.push_back( MyClass1(new MyClass2) );
> 
>   std::cout << "End of main." << std::endl;
> }
> 
> -----------------------------------------------------------------
> 
> Hello!
> 
> The code pasted above will call the destructor for the same object twice.
My
> guess is that when calling v.push_back, a temporary variable of the
argument
> is copied to push_back. At the end of push_back the temporary variable is
> destroyed together with  the object it represents. Then again, at the end
of
> the main function, the element in the vector is destroyed, which will lead
> to the same object being destroyed again.
> 
> I was wondering if it's possible to fix this problem without having to
> change the code in the main function? Any ideas are very much appreciated.

You have identified the problem exactly.  This is a specific example of
violating
"The Rule of Three" - if you need one of destructor, copy constructor, 
and assignment operator, you need all three.

My initial reaction is that MyClass1 should have a std::shared_ptr to 
MyClass2 rather a raw MyClass2*.  With that, MyClass1 doesn't even need a
user
defined destructor - the memberwise destruction of the shared_ptr will do 
everything for you.

Alternatively, you might want to make the copy constructor and assignment
operator of MyClass1 to make a copy of MyClass2.  If you write the
assignment
operator as:

const MyClass1& operator =(const MyClass1& lhs)
{
  MyClass1 copy(lhs);  // take copy.
  // Exception free operations only from this point ...
  std::swap( this->mc2, copy.mc2 );
}

You will be safe from problems if you do self assignment (which can happen
when you end up passing references through a few layers of templates), or if
copy construction can throw.

There may be some more options introduced by C++11, but I suspect you would
be best keeping things simple.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Martin
5/11/2015 11:57:01 AM
On 11/05/2015 18:57, Martin Bonner wrote:
>
> On Monday, 11 May 2015 13:20:09 UTC+1, goforgit  wrote:
>> #include <iostream>
>> #include <vector>
>>
>> class MyClass2 {
>> public:
>>
>>    MyClass2() {
>>      std::cout << "MyClass2: Constructor." << std::endl;
>>    }
>>
>>    ~MyClass2() {
>>      std::cout << "MyClass2: Destructor." << std::endl;
>>    }
>>
>> };
>>
>> class MyClass1 {
>> public:
>>
>>    MyClass1(MyClass2 * m) {  // new pointer to m
>>      std::cout << "MyClass1: Constructor." << std::endl;
>>      mc2 = m;
>>    }
>>
>>    ~MyClass1() {
>>      std::cout << "MyClass1: Destructor." << std::endl;
>>      delete mc2;
>>    }
>>
>> private:
>>    MyClass2* mc2;
>> };
>>
>> int main () {
>>
>>    std::vector<MyClass1> v;
>>    v.push_back( MyClass1(new MyClass2) );
>>
>>    std::cout << "End of main." << std::endl;
>> }
>>
>> -----------------------------------------------------------------
>>
>> Hello!
>>
>> The code pasted above will call the destructor for the same object twice.
> My
>> guess is that when calling v.push_back, a temporary variable of the
> argument
>> is copied to push_back. At the end of push_back the temporary variable is
>> destroyed together with  the object it represents. Then again, at the end
> of
>> the main function, the element in the vector is destroyed, which will
lead
>> to the same object being destroyed again.
>>
>> I was wondering if it's possible to fix this problem without having to
>> change the code in the main function? Any ideas are very much
appreciated.
>
> You have identified the problem exactly.  This is a specific example of
> violating
> "The Rule of Three" - if you need one of destructor, copy constructor,
> and assignment operator, you need all three.
>
> My initial reaction is that MyClass1 should have a std::shared_ptr to
> MyClass2 rather a raw MyClass2*.  With that, MyClass1 doesn't even need a
> user
> defined destructor - the memberwise destruction of the shared_ptr will do
> everything for you.
>
> Alternatively, you might want to make the copy constructor and assignment
> operator of MyClass1 to make a copy of MyClass2.  If you write the
> assignment
> operator as:
>
> const MyClass1& operator =(const MyClass1& lhs)
> {
>    MyClass1 copy(lhs);  // take copy.
>    // Exception free operations only from this point ...
>    std::swap( this->mc2, copy.mc2 );
> }
>
> You will be safe from problems if you do self assignment (which can happen
> when you end up passing references through a few layers of templates), or
if
> copy construction can throw.
>
> There may be some more options introduced by C++11, but I suspect you
would
> be best keeping things simple.
>
>
How does the rule of 3 help here? push_back requires an object to copy. 
Possibly a move ctor can save some overhead but then you have C++11 and 
then you would be using emplace_back() rather than push_back().


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Francis
5/11/2015 4:07:46 PM
[Please do not mail me a copy of your followup]

Francis Glassborow <francis.glassborow@btinternet.com> spake the secret code
<mir0n4$llf$1@dont-email.me> thusly:

>How does the rule of 3 help here? push_back requires an object to copy. 
>Possibly a move ctor can save some overhead but then you have C++11 and 
>then you would be using emplace_back() rather than push_back().

emplace_back only constructs a new object on the back of the vector,
it doesn't eliminate the need for the elements to be copyable.  See
the documentation for std::vector:
<http://en.cppreference.com/w/cpp/container/vector>

Template parameters:

T - The type of the elements.

    T must meet the requirements of CopyAssignable and
	CopyConstructable.

This is a fundamental imposition on the template parameter made by
std::vector.  Whether you use emplace_back or push_back doesn't change
this.

The wording in the reference above relaxes the requirements on T for
C++11 and beyond saying that the requirements depend on the member
functions invoked on the vector.

Basically they're saying that T doesn't need to be CopyAssignable if
you never do anything to the vector that causes it to reallocate space
and copy over the contained elements.  While I understand this wording,
I basically consider that to be expert territory and my advice is that
until you have a specific reason you should ensure that your objects
are CopyAssignable and CopyConstructable when you use them in std::vector.
-- 
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
     The Computer Graphics Museum <http://computergraphicsmuseum.org>
         The Terminals Wiki <http://terminals.classiccmp.org>
  Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
legalize
5/11/2015 6:12:26 PM
On Monday, 11 May 2015 22:10:07 UTC+1, Francis Glassborow  wrote:
> On 11/05/2015 18:57, Martin Bonner wrote:
> >
> > On Monday, 11 May 2015 13:20:09 UTC+1, goforgit  wrote:
> >> #include <iostream>
> >> #include <vector>
> >>
> >> class MyClass2 {
> >> public:
> >>
> >>    MyClass2() {
> >>      std::cout << "MyClass2: Constructor." << std::endl;
> >>    }
> >>
> >>    ~MyClass2() {
> >>      std::cout << "MyClass2: Destructor." << std::endl;
> >>    }
> >>
> >> };
> >>
> >> class MyClass1 {
> >> public:
> >>
> >>    MyClass1(MyClass2 * m) {  // new pointer to m
> >>      std::cout << "MyClass1: Constructor." << std::endl;
> >>      mc2 = m;
> >>    }
> >>
> >>    ~MyClass1() {
> >>      std::cout << "MyClass1: Destructor." << std::endl;
> >>      delete mc2;
> >>    }
> >>
> >> private:
> >>    MyClass2* mc2;
> >> };
> >>
> >> int main () {
> >>
> >>    std::vector<MyClass1> v;
> >>    v.push_back( MyClass1(new MyClass2) );
> >>
> >>    std::cout << "End of main." << std::endl;
> >> }
> >>
> >> -----------------------------------------------------------------
> >>
> >> Hello!
> >>
> >> The code pasted above will call the destructor for the same object
twice.
> > My
> >> guess is that when calling v.push_back, a temporary variable of the
> > argument
> >> is copied to push_back. At the end of push_back the temporary variable
is
> >> destroyed together with  the object it represents. Then again, at the
end
> > of
> >> the main function, the element in the vector is destroyed, which will
> lead
> >> to the same object being destroyed again.
> >>
> >> I was wondering if it's possible to fix this problem without having to
> >> change the code in the main function? Any ideas are very much
> appreciated.
> >
> > You have identified the problem exactly.  This is a specific example of
> > violating
> > "The Rule of Three" - if you need one of destructor, copy constructor,
> > and assignment operator, you need all three.
> >
> > My initial reaction is that MyClass1 should have a std::shared_ptr to
> > MyClass2 rather a raw MyClass2*.  With that, MyClass1 doesn't even need
a
> > user
> > defined destructor - the memberwise destruction of the shared_ptr will
do
> > everything for you.
> >
> > Alternatively, you might want to make the copy constructor and
assignment
> > operator of MyClass1 to make a copy of MyClass2.  If you write the
> > assignment
> > operator as:
> >
> > const MyClass1& operator =(const MyClass1& lhs)
> > {
> >    MyClass1 copy(lhs);  // take copy.
> >    // Exception free operations only from this point ...
> >    std::swap( this->mc2, copy.mc2 );
> > }
> >
> > You will be safe from problems if you do self assignment (which can
happen
> > when you end up passing references through a few layers of templates),
or
> if
> > copy construction can throw.
> >
> > There may be some more options introduced by C++11, but I suspect you
> would
> > be best keeping things simple.
> >
> >
> How does the rule of 3 help here? push_back requires an object to copy. 
> Possibly a move ctor can save some overhead but then you have C++11 and 
> then you would be using emplace_back() rather than push_back().

The rule of 3 helps here by saying "you need to provide a working copy
constructor".  The default (compiler supplied) copy constructor will copy
the
value of the raw pointer mc2, and that doesn't work if the destructor is
going 
to call "delete mc2;"

As you observe, you also need to provide a working assignment operator, but
in
this particular example, it's quite likely that the assignment operator is
never called.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Martin
5/12/2015 6:57:24 AM
On Monday, 11 May 2015 18:00:07 UTC+1, Francis Glassborow  wrote:
> On 11/05/2015 14:16, teztingit@googlemail.com wrote:
> >
> > #include <iostream>
> > #include <vector>
> >
> > class MyClass2 {
> > public:
> >
> >    MyClass2() {
> >      std::cout << "MyClass2: Constructor." << std::endl;
> >    }
> >
> >    ~MyClass2() {
> >      std::cout << "MyClass2: Destructor." << std::endl;
> >    }
> >
> > };
> >
> > class MyClass1 {
> > public:
> >
> >    MyClass1(MyClass2 * m) {  // new pointer to m
> >      std::cout << "MyClass1: Constructor." << std::endl;
> >      mc2 = m;
> >    }
> >
> >    ~MyClass1() {
> >      std::cout << "MyClass1: Destructor." << std::endl;
> >      delete mc2;
> >    }
> >
> > private:
> >    MyClass2* mc2;
> > };
> >
> > int main () {
> >
> >    std::vector<MyClass1> v;
> >    v.push_back( MyClass1(new MyClass2) );
> >
> >    std::cout << "End of main." << std::endl;
> > }
> >
> > -----------------------------------------------------------------
> >
> > Hello!
> >
> > The code pasted above will call the destructor for the same object
twice.
> My
> > guess is that when calling v.push_back, a temporary variable of the
> argument
> > is copied to push_back. At the end of push_back the temporary variable
is
> > destroyed together with  the object it represents. Then again, at the
end
> of
> > the main function, the element in the vector is destroyed, which will
lead
> > to the same object being destroyed again.
> >
> > I was wondering if it's possible to fix this problem without having to
> > change the code in the main function? Any ideas are very much
appreciated.
> >
> > Thanks in advance!
> >
> >
> But it isn't the same object
Yes it is!  The OP is not referring to the same MyClass1 object being
deleted
twice.  The problem is that there is only ever one MyClass2 object, and it
is
being deleted twice.

> copies and clones are objects in their own right.

Yes - but nothing arranges to copy or clone the MyClass2 object.

> In order to push_back and object you need one, however in order to add 
> an object to a vector you need to construct it in the vector's memory 
> space. 
> If you want to avoid two objects and therefore two destructor 
> calls you need to construct the object in place.

Avoiding two MyClass1 objects is expert-level stuff.  I wouldn't worry
myself.
I'd just arrange _either_ to ensure there *are* two MyClass2 object to
delete
(via suitable copy constructor/assignment) _or_ (better) ensure the single
MyClass2 object is only deleted once (via shared_ptr).


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Martin
5/12/2015 6:57:50 AM
On 11/05/2015 14:16, teztingit@googlemail.com wrote:
>
> #include <iostream>
> #include <vector>
>
> class MyClass2 {
> public:
>
>    MyClass2() {
>      std::cout << "MyClass2: Constructor." << std::endl;
>    }
>
>    ~MyClass2() {
>      std::cout << "MyClass2: Destructor." << std::endl;
>    }
>
> };
>
> class MyClass1 {
> public:
>
>    MyClass1(MyClass2 * m) {  // new pointer to m
>      std::cout << "MyClass1: Constructor." << std::endl;
>      mc2 = m;
>    }
>
>    ~MyClass1() {
>      std::cout << "MyClass1: Destructor." << std::endl;
>      delete mc2;
>    }
>
> private:
>    MyClass2* mc2;
> };
>
> int main () {
>
>    std::vector<MyClass1> v;
>    v.push_back( MyClass1(new MyClass2) );
>
>    std::cout << "End of main." << std::endl;
> }
>
> -----------------------------------------------------------------
>
> Hello!
>
> The code pasted above will call the destructor for the same object twice.
My
> guess is that when calling v.push_back, a temporary variable of the
argument
> is copied to push_back. At the end of push_back the temporary variable is
> destroyed together with  the object it represents. Then again, at the end
of
> the main function, the element in the vector is destroyed, which will lead
> to the same object being destroyed again.
>
> I was wondering if it's possible to fix this problem without having to
> change the code in the main function? Any ideas are very much appreciated.
>
> Thanks in advance!
>
>
Sorry for my earlier responses as I had not read the code with 
sufficient attention, probably because it is many years since I saw code 
that fell into this kind of trap.

IMO the design is very fragile requiring users to understand the class 
design/requirements and no amount of playing around with copy ctors etc. 
will fix it.

MyClass1 contains a pointer to an externally created MyClass1 object 
(and has no knowledge as to how that object was created). It then 
assumes responsibility for its destruction. This must be wrong. It is 
just an accident waiting to happen.

As basic guidelines
1) dtors should only delete sub-objects actually owned by the object. 
Passing around raw pointers does not transfer ownership.
2) Do not use 'new' within the argument list passed to a function, 
including ctors.

Francis



-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Francis
5/13/2015 7:00:43 AM
[Please do not mail me a copy of your followup]

Francis Glassborow <francis.glassborow@btinternet.com> spake the secret code
<miv1k8$24k$1@dont-email.me> thusly:

>As basic guidelines
>1) dtors should only delete sub-objects actually owned by the object. 
>Passing around raw pointers does not transfer ownership.
>
>2) Do not use 'new' within the argument list passed to a function, 
>including ctors.

While these two guidelines are consistent, they aren't the only guidelines
that work.

I've worked in code bases that had no problems using raw pointers as
arguments and used some kind of smart pointer (such as
std::unique_ptr<>) to indicate ownership in the data member.

Using a smart pointer makes it explicit who is managing the raw
pointer and how it is managed (is it exclusively owned or shared?).

I've worked in code bases where instead of thinking about ownership,
the attitude was just to pass shared_ptr in and out of everything.
IMO, this just adds noise to the source code and results in smart
pointer reference counts being needlessly incremented and decremented
every time you call a function and it obscures resource ownership and
lifetime.

IMO, you get better designs by thinking about ownership and lifetime
of resources than you get by taking a Java approach and making
shared_ptr be your poor man's garbage collector and cleaning up your
messes.
-- 
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
     The Computer Graphics Museum <http://computergraphicsmuseum.org>
         The Terminals Wiki <http://terminals.classiccmp.org>
  Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
legalize
5/13/2015 2:10:45 PM
Thanks guys. Reading the answers has really helped me to better understand
what I should do to avoid these kind of problems and how to fix them. As
pointed out by Martin Bonner, making sure that the code does not violate the
rule of three (by defining a copy constructor) solved this problem.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
goforgit
5/14/2015 6:35:17 AM
On Wednesday, 13 May 2015 22:20:08 UTC+3, Richard  wrote:
> 
> Francis Glassborow <francis.glassborow@btinternet.com> spake the secret
code
> <miv1k8$24k$1@dont-email.me> thusly:
> 
> >As basic guidelines
> >1) dtors should only delete sub-objects actually owned by the object. 
> >Passing around raw pointers does not transfer ownership.
> >
> >2) Do not use 'new' within the argument list passed to a function, 
> >including ctors.
> 
> While these two guidelines are consistent, they aren't the only guidelines
> that work.
> 
> I've worked in code bases that had no problems using raw pointers as
> arguments and used some kind of smart pointer (such as
> std::unique_ptr<>) to indicate ownership in the data member.

Francis did not write that raw pointers may not be passed around. 
He wrote that these should not transfer ownership of pointed at
object from caller to callee. Same is what style guides (that allow
raw pointer parameters at all) typically suggest.

For example Google's C++ coding style guide requires lvalue
reference to const  parameter or by value parameter as "IN" 
parameters and pointer to non-const for "IN-OUT" or "OUT"
parameters:
http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Reference
Arguments 
http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Function
Parameter Ordering

How it contradicts with guidelines of Francis?

> Using a smart pointer makes it explicit who is managing the raw
> pointer and how it is managed (is it exclusively owned or shared?).
>
> I've worked in code bases where instead of thinking about ownership,
> the attitude was just to pass shared_ptr in and out of everything.
> IMO, this just adds noise to the source code and results in smart
> pointer reference counts being needlessly incremented and decremented
> every time you call a function and it obscures resource ownership and
> lifetime.

Sure, 'unique_ptr' should be the most typical smart pointer and
it is perfect (as by value parameter) for transferring ownership. 
How they use 'shared_ptr' in context of ownership transfer?  IMO
'shared_ptr' should be *only* used in the very rare case of actually
shared ownership.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
ISO
5/14/2015 4:18:54 PM
On 14/05/2015 13:35, goforgit wrote:
>
> Thanks guys. Reading the answers has really helped me to better understand
> what I should do to avoid these kind of problems and how to fix them. As
> pointed out by Martin Bonner, making sure that the code does not violate the
> rule of three (by defining a copy constructor) solved this problem.
>
>
Not really, it hid the more fundamental one of ownership of an object 
(created with new)  Whenever an object is created dynamically with 'new' 
it is important to manage its lifetime. Smart pointers are often a good 
way to go.

Here is a simplified version of your code:

struct fuse{
     int i;
};


struct bomb {
   fuse * f;
   bomb (fuse * f1) f(f1) ();
   ~bomb (){ delete f; }
};

~bomb() assumes that f points to an object that has been created with 
new. But there is nothing in the class bomb that ensures that that is 
true and if it isn't your code is badly broken and will blow up at the 
most inconvenient time.

Now change the ctor to:
   bomb(): f(new fuse) {}

and that problem goes away, bonb owns its fuse. When you now write your 
copy ctor and operator = you can decide what to do about the fuse 
because the bomb instance owns a fuse it was responsible for making.

As a general rule when using new either the scope in which the object is 
created is the one in which delete is called or you need to provide a 
mechanism to transfer ownership to something that will delete it.

Francis




-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Francis
5/14/2015 4:19:51 PM
Reply:

Similar Artilces:

methods to call matlab in C C++ and call C C++ in matlab
Hi, I am reading the help documents about how to program matlab and C C++ together and my questions are a little bit general. It seems that are several ways to call matlab in C C++ and another several ways to call C C++ in matlab. Please correct me if I am wrong or missing something when I try to list them. To call matlab code in C C++, are there two methods available? The first one is Matlab engine and the second one is to use MATLAB Compiler mcc to create C or C++ shared libraries from your MATLAB code. To call C C++ in matlab, are there also two methods? The first one is to call funct...

c++ calling java calling c++ ...
Hi, i'm currently working on a plugin for Adobe InDesign and i have some problems with that. I'm not really a c++ guru, maybe somebody here has an idea how to solve this. The plugin is written in C++ and it's calling a java application. This application displays a window and pushing a button is calling back the c++-plugin again. // The plugin class. CActionComponent is part of the InDesign SDK class MyJNIComponent : public CActionComponent { public: ... static void onCreateDocument(); ... private: ... void registerCallbacks(); ... } // this is called fr...

c++ calling fortran and fortran calling C++
Hi, For my application in C++, I need to call a subtroutine in fortran. This subroutine must call a function of my program. I'm trying to use pointer of my function but I have segmentation fault. the fortran code is: subroutine dlltest [dllexport] (c_msg,e1,e2,e3,i,r,d,str) c implicit none integer i,l,m,length real*4 r double precision d character*128 e1,e2,e3,str,aux,aux2 external c_msg,length c first, write parameters to a file open(1,file='test.out',status='unknown') rewind(1) c write(1,*) 'function pointer: ',c_msg write(1,*) 'integer: ...

Destructor being called twice ?
Hi , Have the following piece of code , class ClientList { public: char * hostName ; int portNo ; struct timeval * tv ; ClientList () { this -> hostName = new char [40] ; .... } ~ClientList () { delete [] (this -> hostName) ; } }; While running , everything works fine and the destructor is called. But it seems like the compiler tries to free this memory again on its own , giving the following error on g++ *** glibc detected *** double free or corruption (fasttop): 0x0804d008 *** is there something wrong which is being done h...

Destructor being called twice?
I have written a class with my own constructor and destructor. I declare an object of this class globally. The class is constructed just fine, but when the program exits, the destructor is being called twice for some reason unknown to me. This is causing a seg fault, since I am trying to write to a file from a string array in the destructor, and the 2nd time the destructor is called, it writes anywhere from 80-100k of garbage to my file. I am *not* calling this destructor anywhere in the program, it should only be called once (implicitly) upon program end. Any idea what I'm d...

Should I call C from LabVIEW or call LabVIEW from C?
I need to write some software and am trying to choose the best development environment. I currently use Borland C++ Builder to develop most of my software and have also used some LabVIEW occasionally. The new package I need to write has to provide several functions, some of which would be better in C++, some in LabVIEW and I am wondering whether to combine the two. So far, I have had a quick play around and called a very basic piece LabVIEW code, built into a dll, from some C++ code. I am about to try to reverse (create dll in C++ and call from LabVIEW) but would appreciate some advice on the ...

destructor called twice
Hi, I have the following simple code - #include <iostream> #include "Event.h" int main() { { Event event; std::pair<double,Event>(0.1,event); } std::cin.get(); return 0; } #ifndef EVENT_H #define EVENT_H #include <iostream> class Event { public: Event(void); virtual ~Event(void); }; #endif #include "Event.h" Event::Event() { std::cout << "Event()" << std::endl; } Event::~Event() { std::cout << "~Event()" << std::endl; } Why is the output as follows - Event() ~Event() ~Event() Sinc...

C++ destructor not being called?
I create a pthread that calls op() on an object of the class below. The problem I'm having is this, my ThreadSafeQueue object holds MethodRequest objects that were newed in a different thread and deleted in this thread (at the bottom of the 'while' block.) I know they are deleted because I have a cout in the smart pointer's destructor showing the delete is getting called. However, the destructor isn't getting called. Any clues as to what is going wrong? The only thing that I can think of that I haven't tried is to put a mutex in the smart pointer, but t...

C++ DLL calling and being called by C propgram?
Hi, I Extend a program that us C . It allows us to etxtend it thru DLLs. How can i write a C++ DLL that can interface with the C main program . the DLL must provide a few call back function for the main program to call. How can it be done? seewan Here it is. in DLL: MyDllFunc.h .... extern "C" { int DllFunc1(int,int); /* whatever params */ void DllFunc2(int); /* whatever params */ }; .... MyDllFunc.cpp #include "MyDllFunc.h" int DllFunc1(int arg1,int arg2) { /* function body */ } void DllFunc2(int...

Destructor calling order from function calls different from <Effective C++>
Hey, In the book <Effective C++>, the author provides an example to prove why we need "pass by reference". I redoed the example, and found something interesting. The codes are: ############################## #include <iostream> class Student{ public: Student(){ std::cout << "inside CTOR. this = " << this << std::endl << std::endl; } Student(const Student& rhs){ std::cout << "inside COPY CTOR. this = " << this << ", rhs = "<< &rhs << std::endl <<...

What is the different between c++ call convention and c call convention?
What is the different between c++ call convention and c call convention?Can some give some examples? On Thu, 6 Dec 2007 19:25:57 -0800 (PST), dolphin <jdxyw2004@gmail.com> wrote in comp.lang.c++: > What is the different between c++ call convention and c call > convention?Can some give some examples? Neither C nor C++ define a "calling convention". Particular compilers provide their own "calling conventions", generally based on the underlying processor architecture and usually also on the operating system that the code will run under. If you are interested i...

how to call C++ from C?
I have some C++ code that I would like to call from within a C program (main() is within the C code). How do I go about doing this portably? I know that I can find the mangled name of the C++ functions, but this is kind of weird. I am using gcc and g++ on Linux, if that matters. Here is an example of what I'm doing: --------------------------------------------------- a.c: --------------------------------------------------- #include "b.h" int main() { foo(); } --------------------------------------------------- b.h --------------------------------------------------- in...

Call C++ from C
Hello, how can I call this C++ Code from C? I must use C, because Ruby-ffi understand only C. [code] class Shape { public: Shape() { nshapes++; } virtual ~Shape() { nshapes--; }; double x, y; void move(double dx, double dy); virtual double area(void) = 0; virtual double perimeter(void) = 0; static int nshapes; }; class Circle : public Shape { private: double radius; public: Circle(double r) : radius(r) { }; virtual double area(void); virtual double perimeter(void); }; class Square : public Shape { private: double width; public: Square(double w) : ...

why destructor function called twice
Hi all, something wrong with my code, it seems that the destructor function has been called twice. I don't know why.here is my codes Fixture.h #ifndef _FIXTURE_H #define _FIXTURE_H #include <string> #include <map> #include <list> #include <vector> #include <utility> #include <algorithm> using namespace std; class Fixture { protected: string fixturename; vector<string>faces map<string,vector<string> > points; map<string,string>locators; public: Fixture(); Fixture(const Fixture &fix); ~Fixture(); ...

Web resources about - Destructor called twice - comp.lang.c++.moderated

Varroa destructor - Wikipedia, the free encyclopedia
Varroa destructor is an external parasitic mite that attacks the honey bees Apis cerana and Apis mellifera . The disease caused by the mites ...

Microsoft – The New Destructor of Innovation?
If you read our blog from time to time, you'll know that Brad and I dislike the U.S. patent system with a particular distate for software patents. ...

Choose the form of your Ghostbusters donut destructor
Promising to make your stomach feel like the floor of a taxicab, Krispy Kreme has announced that it will celebrate the 30th anniversary of Ghostbusters ...

Mitt Romney, Uncreative Destructor by @DavidOAtkins
Mitt Romney, Uncreative Destructor by David Atkins Mitt Romney had a fascinating take on the foreclosure mess today. Dave Dayen has a superb ...

Crave 79: Choose the form of the Destructor
Empty your heads. Don't think of anything. Whatever happens, don't think of DARPA's talon-limbed Cheetah robot.

Destructors Considered Harmful
Allocating dynamic resources may seem hazardous but freeing them is the real hazard.

Transformers: Fall of Cybertron multiplayer faces Dinobot Destructor Pack next week
... robots will meet the eye in Transformers: Fall of Cybertron multiplayer next week. Game director Matt Tieger told Polygon that a "Dinobot Destructor ...

Varroa destructor mite mimics two types of bee
The parasitic bee mite Varroa destructor, which can mimic the chemical composition of its host's cuticle, is also capable of adapting this composition ...

Microsoft - The New Destructor of Innovation
The web's technology news site of record, Techmeme spotlights the hottest tech stories from all around the web on a single page.

Glenn Reynolds: Liberals have chosen The Donald as their 'Destructor'
Weak and ineffectual leadership created the vacuum Trump is filling. “Choose the form of the Destructor,” says the demon in Ghostbusters . Bill ...

Resources last updated: 1/25/2016 4:28:58 PM