[c++]Why is my class destructor called twice? -


i have such code like,

#include <iostream> #include <string>  using namespace std;  class heart { private:     int bpm; public:     heart(int bpm) : bpm(bpm) {}     int getbpm() {         return bpm;     } };  class kidney { private:     double percentfunction; public:     kidney() : percentfunction(0) {}     kidney(double pf) : percentfunction(pf) {}     double getpf() {         return percentfunction;     } };  class person { private:     string fname, lname;     int age;     heart h;     kidney* k;   public:     person(string fn, string ln, int age, int bpm, double kpf1, double kpf2) : fname(fn), lname(ln), age(age), h(bpm) {         k = new kidney[2];         k[0] = kidney(kpf1);         k[1] = kidney(kpf2);         cout << fname << " " << lname << ", aged " << age << ". heart bpm : " << bpm <<             ". kidneys' percent function indices: " << k[0].getpf() << " , " << k[1].getpf() << '.' << endl;     }     ~person() {         cout << "a person dying!" << endl;         delete[] k;     }   };   int main() {     person p = person("jack", "bowen", 24, 60, 0.99, 0.98); } 

then run code, error(debug assertion failed!) pops up. , can see destructor called twice. if remove delete [] k; in ~person, there no such pop-up error.

there dynamic allocation in person constructor:

k = new kidney[2]; k[0] = kidney(kpf1); k[1] = kidney(kpf2); 

so think should delete k in destructor. question why destructor called twice , how solve error?

i using vs 2013.

thank you!

the issue following. in line

person p = person("jack", "bowen", 24, 60, 0.99, 0.98); 

you copy-initializing p, i.e. creating temporary copied person p;. @ end, temporary person("jack", "bowen", 24, 60, 0.99, 0.98); destroyed, kidney* pointer dangling, because didn't implement copy constructor , copy shallow (i.e. pointer being copied, not object points to). , destructor called twice because first called when temporary ends life (at end of statement), again when person p goes out of scope @ end of main().

anytime class has pointer, implement copy constructor , assignment operator. or better, use smart pointers std::shared_ptr, or better, standard containers keep track of dynamic memory std::vector/std::list etc.

quick , dirty fix code (but really, must implement copy constructor since you're going have other kinds of issues, e.g. when returning persons function or when passing persons value):

person p("jack", "bowen", 24, 60, 0.99, 0.98); 

this avoids temporary , uses direct initialization.

ps: in g++, compiling -weffc++ warns these issues,

warning: 'class person' has pointer data members [-weffc++] not override 'person(const person&)' [-weffc++] or 'operator=(const person&)' [-weffc++]

i not sure if such compiler flag exists vs though.


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -