C++ make_shared calling destructor twice [closed]












2















I have some code that's confusing me. I've been learning about shared_pointers and am following a guide on youtube. I am using make_shared to construct my Dog, and assign the shared pointer to p.



class Dog
{
private:
std::string name;
public:
Dog(std::string _name):
name(_name)
{
std::cout << "Creating dog with name " << name << std::endl;
}

~Dog() { std::cout << "Destroying dog!" << std::endl; }

void bark()
{
std::cout << name << " barks like a Dog! Woof!" << std::endl;
}
};

std::shared_ptr<Dog> foo()
{
std::cout << "Entering foo" << std::endl;
std::shared_ptr<Dog> p = std::make_shared<Dog>("Tank"); //will be deleted when freed off stack

std::cout << "Dog use count = " << p.use_count() << std::endl;

std::shared_ptr<Dog> p2 = p;

std::cout << "Dog use count = " << p.use_count() << std::endl;

std::cout << "Returning first pointer from foo!" << std::endl;
return p;
}
int main()
{
std::shared_ptr<Dog> p = foo();

std::cout << "Dog use count = " << p.use_count() << std::endl;

return 0;
}


Compiled with



g++ shared_ptr.cpp


However, here is my output:



Entering foo
Creating dog with name Tank
Destroying dog!
Destroying dog!
Dog use count = 1
Dog use count = 2
Returning first pointer from foo!


Could someone explain the logic of constructing and then double destructing somehow?










share|improve this question















closed as off-topic by VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru Nov 28 '18 at 21:44


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru

If this question can be reworded to fit the rules in the help center, please edit the question.












  • 3





    You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.

    – tadman
    Nov 28 '18 at 21:02






  • 5





    I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?

    – NathanOliver
    Nov 28 '18 at 21:02






  • 3





    Tip: Accept string arguments as const std::string& to avoid making endless, pointless copies.

    – tadman
    Nov 28 '18 at 21:02






  • 2





    You should show the code calling foo. Also note that Dog class has implicit copy constructor and assignment operators.

    – VTT
    Nov 28 '18 at 21:04













  • @tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.

    – Brian
    Nov 28 '18 at 21:04


















2















I have some code that's confusing me. I've been learning about shared_pointers and am following a guide on youtube. I am using make_shared to construct my Dog, and assign the shared pointer to p.



class Dog
{
private:
std::string name;
public:
Dog(std::string _name):
name(_name)
{
std::cout << "Creating dog with name " << name << std::endl;
}

~Dog() { std::cout << "Destroying dog!" << std::endl; }

void bark()
{
std::cout << name << " barks like a Dog! Woof!" << std::endl;
}
};

std::shared_ptr<Dog> foo()
{
std::cout << "Entering foo" << std::endl;
std::shared_ptr<Dog> p = std::make_shared<Dog>("Tank"); //will be deleted when freed off stack

std::cout << "Dog use count = " << p.use_count() << std::endl;

std::shared_ptr<Dog> p2 = p;

std::cout << "Dog use count = " << p.use_count() << std::endl;

std::cout << "Returning first pointer from foo!" << std::endl;
return p;
}
int main()
{
std::shared_ptr<Dog> p = foo();

std::cout << "Dog use count = " << p.use_count() << std::endl;

return 0;
}


Compiled with



g++ shared_ptr.cpp


However, here is my output:



Entering foo
Creating dog with name Tank
Destroying dog!
Destroying dog!
Dog use count = 1
Dog use count = 2
Returning first pointer from foo!


Could someone explain the logic of constructing and then double destructing somehow?










share|improve this question















closed as off-topic by VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru Nov 28 '18 at 21:44


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru

If this question can be reworded to fit the rules in the help center, please edit the question.












  • 3





    You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.

    – tadman
    Nov 28 '18 at 21:02






  • 5





    I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?

    – NathanOliver
    Nov 28 '18 at 21:02






  • 3





    Tip: Accept string arguments as const std::string& to avoid making endless, pointless copies.

    – tadman
    Nov 28 '18 at 21:02






  • 2





    You should show the code calling foo. Also note that Dog class has implicit copy constructor and assignment operators.

    – VTT
    Nov 28 '18 at 21:04













  • @tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.

    – Brian
    Nov 28 '18 at 21:04
















2












2








2








I have some code that's confusing me. I've been learning about shared_pointers and am following a guide on youtube. I am using make_shared to construct my Dog, and assign the shared pointer to p.



class Dog
{
private:
std::string name;
public:
Dog(std::string _name):
name(_name)
{
std::cout << "Creating dog with name " << name << std::endl;
}

~Dog() { std::cout << "Destroying dog!" << std::endl; }

void bark()
{
std::cout << name << " barks like a Dog! Woof!" << std::endl;
}
};

std::shared_ptr<Dog> foo()
{
std::cout << "Entering foo" << std::endl;
std::shared_ptr<Dog> p = std::make_shared<Dog>("Tank"); //will be deleted when freed off stack

std::cout << "Dog use count = " << p.use_count() << std::endl;

std::shared_ptr<Dog> p2 = p;

std::cout << "Dog use count = " << p.use_count() << std::endl;

std::cout << "Returning first pointer from foo!" << std::endl;
return p;
}
int main()
{
std::shared_ptr<Dog> p = foo();

std::cout << "Dog use count = " << p.use_count() << std::endl;

return 0;
}


Compiled with



g++ shared_ptr.cpp


However, here is my output:



Entering foo
Creating dog with name Tank
Destroying dog!
Destroying dog!
Dog use count = 1
Dog use count = 2
Returning first pointer from foo!


Could someone explain the logic of constructing and then double destructing somehow?










share|improve this question
















I have some code that's confusing me. I've been learning about shared_pointers and am following a guide on youtube. I am using make_shared to construct my Dog, and assign the shared pointer to p.



class Dog
{
private:
std::string name;
public:
Dog(std::string _name):
name(_name)
{
std::cout << "Creating dog with name " << name << std::endl;
}

~Dog() { std::cout << "Destroying dog!" << std::endl; }

void bark()
{
std::cout << name << " barks like a Dog! Woof!" << std::endl;
}
};

std::shared_ptr<Dog> foo()
{
std::cout << "Entering foo" << std::endl;
std::shared_ptr<Dog> p = std::make_shared<Dog>("Tank"); //will be deleted when freed off stack

std::cout << "Dog use count = " << p.use_count() << std::endl;

std::shared_ptr<Dog> p2 = p;

std::cout << "Dog use count = " << p.use_count() << std::endl;

std::cout << "Returning first pointer from foo!" << std::endl;
return p;
}
int main()
{
std::shared_ptr<Dog> p = foo();

std::cout << "Dog use count = " << p.use_count() << std::endl;

return 0;
}


Compiled with



g++ shared_ptr.cpp


However, here is my output:



Entering foo
Creating dog with name Tank
Destroying dog!
Destroying dog!
Dog use count = 1
Dog use count = 2
Returning first pointer from foo!


Could someone explain the logic of constructing and then double destructing somehow?







c++ shared-ptr






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 28 '18 at 21:45







briansrls

















asked Nov 28 '18 at 20:59









briansrlsbriansrls

446317




446317




closed as off-topic by VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru Nov 28 '18 at 21:44


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru

If this question can be reworded to fit the rules in the help center, please edit the question.







closed as off-topic by VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru Nov 28 '18 at 21:44


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru

If this question can be reworded to fit the rules in the help center, please edit the question.








  • 3





    You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.

    – tadman
    Nov 28 '18 at 21:02






  • 5





    I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?

    – NathanOliver
    Nov 28 '18 at 21:02






  • 3





    Tip: Accept string arguments as const std::string& to avoid making endless, pointless copies.

    – tadman
    Nov 28 '18 at 21:02






  • 2





    You should show the code calling foo. Also note that Dog class has implicit copy constructor and assignment operators.

    – VTT
    Nov 28 '18 at 21:04













  • @tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.

    – Brian
    Nov 28 '18 at 21:04
















  • 3





    You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.

    – tadman
    Nov 28 '18 at 21:02






  • 5





    I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?

    – NathanOliver
    Nov 28 '18 at 21:02






  • 3





    Tip: Accept string arguments as const std::string& to avoid making endless, pointless copies.

    – tadman
    Nov 28 '18 at 21:02






  • 2





    You should show the code calling foo. Also note that Dog class has implicit copy constructor and assignment operators.

    – VTT
    Nov 28 '18 at 21:04













  • @tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.

    – Brian
    Nov 28 '18 at 21:04










3




3





You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.

– tadman
Nov 28 '18 at 21:02





You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.

– tadman
Nov 28 '18 at 21:02




5




5





I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?

– NathanOliver
Nov 28 '18 at 21:02





I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?

– NathanOliver
Nov 28 '18 at 21:02




3




3





Tip: Accept string arguments as const std::string& to avoid making endless, pointless copies.

– tadman
Nov 28 '18 at 21:02





Tip: Accept string arguments as const std::string& to avoid making endless, pointless copies.

– tadman
Nov 28 '18 at 21:02




2




2





You should show the code calling foo. Also note that Dog class has implicit copy constructor and assignment operators.

– VTT
Nov 28 '18 at 21:04







You should show the code calling foo. Also note that Dog class has implicit copy constructor and assignment operators.

– VTT
Nov 28 '18 at 21:04















@tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.

– Brian
Nov 28 '18 at 21:04







@tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.

– Brian
Nov 28 '18 at 21:04














1 Answer
1






active

oldest

votes


















3














I think I've figured it out.



I tried compiling on centos with



g++ shared_ptr.cpp


But the compiler complains that shared_ptr is not a part of std. Changing to



g++ -std=c++11 shared_ptr.cpp


makes compilation successful, and I see the behavior I would expect (no double destruction).



My mac's makefile only specified



g++ shared_ptr.cpp


I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.



On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.






share|improve this answer






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    I think I've figured it out.



    I tried compiling on centos with



    g++ shared_ptr.cpp


    But the compiler complains that shared_ptr is not a part of std. Changing to



    g++ -std=c++11 shared_ptr.cpp


    makes compilation successful, and I see the behavior I would expect (no double destruction).



    My mac's makefile only specified



    g++ shared_ptr.cpp


    I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.



    On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.






    share|improve this answer




























      3














      I think I've figured it out.



      I tried compiling on centos with



      g++ shared_ptr.cpp


      But the compiler complains that shared_ptr is not a part of std. Changing to



      g++ -std=c++11 shared_ptr.cpp


      makes compilation successful, and I see the behavior I would expect (no double destruction).



      My mac's makefile only specified



      g++ shared_ptr.cpp


      I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.



      On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.






      share|improve this answer


























        3












        3








        3







        I think I've figured it out.



        I tried compiling on centos with



        g++ shared_ptr.cpp


        But the compiler complains that shared_ptr is not a part of std. Changing to



        g++ -std=c++11 shared_ptr.cpp


        makes compilation successful, and I see the behavior I would expect (no double destruction).



        My mac's makefile only specified



        g++ shared_ptr.cpp


        I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.



        On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.






        share|improve this answer













        I think I've figured it out.



        I tried compiling on centos with



        g++ shared_ptr.cpp


        But the compiler complains that shared_ptr is not a part of std. Changing to



        g++ -std=c++11 shared_ptr.cpp


        makes compilation successful, and I see the behavior I would expect (no double destruction).



        My mac's makefile only specified



        g++ shared_ptr.cpp


        I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.



        On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 28 '18 at 21:26









        briansrlsbriansrls

        446317




        446317

















            Popular posts from this blog

            Lallio

            Unable to find Lightning Node

            Futebolista