c++runtime-errorc++14shared-ptr

Why, if constructing a shared_ptr from raw pointer, "main()" exits with some negative error code?


Just experimenting with shared_ptr to explore its functionalities. I'm constructing a new shared_ptr object using a raw pointer from other shared_ptr object. The following code is compiling and runs but not quite as expected - the main() exit status is not 0.

It's C++14, console application configuration on VisualStudio 2022.

Here is my code:

#include <iostream>
#include <string>
#include <memory>
#include <exception>
class Dog {
public:
    Dog(std::string name) : m_name(name) {
        std::cout << "Dog " << m_name << " created\n";
    }
    void bark() {
        std::cout << m_name << " wooof\n";
    }
    ~Dog() {
        std::cout << m_name << " removed\n";
    }
private:
    std::string m_name;
};

int main()
{
    std::shared_ptr<Dog> dog_sp(new Dog("Fido"));
    int use_count = dog_sp.use_count();
    printf("use_count1=%d\n", use_count);
    std::shared_ptr<Dog> dog_sp2(dog_sp);
    use_count = dog_sp2.use_count();
    printf("use_count2=%d\n", use_count);

    Dog* dog_ptr = dog_sp.get();

    dog_ptr->bark();
   
    try {
        std::shared_ptr<Dog> dog_sp3(dog_ptr);
        use_count = dog_sp3.use_count();
        dog_sp3->bark();
        printf("use_count3=%d\n", use_count);
    } catch (std::exception& ex) {
        std::cout << "Exception: " << ex.what() << std::endl;
    } catch (const std::string& ex) {
        std::cout << "Exception: " << ex << std::endl;
    } catch (...) {
        std::cout << "Exception" << std::endl;
    }
    return 0;
}

Console Output:

Dog Fido created
use_count1=1
use_count2=2
Fido wooof
Fido wooof
use_count3=1
Fido removed

Running without debugger, get the following status:

shared_ptr.exe (process 50940) exited with code -1073741819.

Running with a debugger and it pops an unhandled exception. So adding some try catch, but nothing is caught there.

Please suggest, what do I miss when constructing a shared_ptr with a raw pointer from other shared_ptr object? Please suggest a use case for constructor 3 here Thank you!


Solution

  • You delete object twice. According to documentation your object is destroyed using delete-expression.

    You can check what happens in the following example with comments

    std::shared_ptr<Dog> dog_sp(new Dog("Fido"));
    
    // You get raw pointer and ownership is still in dog_sp
    Dog* dog_ptr = dog_sp.get();
    
    // You create another shared pointer to raw pointer and now you have two objects 
    // which ARE NOT share ownership of pointer
    std::shared_ptr<Dog> dog_sp3(dog_ptr);
    
    // When your main exits - both shared_ptr release owned pointer, so 
    // you have double free here
    

    The solution: use shared pointers copy constructors or assignments and do not try to take ownership of internal pointer.