Search code examples
c++shared-ptr

C++ make_shared calling destructor twice


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?


Solution

  • 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.