Reputation: 1098
I have a pointer to class initialized by the new
operator. Then I use this pointer to setup a std::unique_ptr
. Now, as far as my understanding goes, the following code has double delete, once the manually called delete
operator and then when the unique pointer goes out of scope. How does this code run "correctly", i.e., without a runtime exception?
#include <iostream>
#include <memory>
class A
{
public:
A()
{
std::cout<<"In A::A()\n";
}
~A()
{
std::cout<<"In A::~A()\n";
}
void printMyStr()
{
std::cout<<"In A::printMyStr()\n";
}
};
int main()
{
std::cout<<"hello world!\n";
A * pa = new A();
std::unique_ptr<A> upa(pa);
pa->printMyStr();
upa->printMyStr();
delete pa; // How does this not create problems?
return 0;
}
Output:
hello world!
In A::A()
In A::printMyStr()
In A::printMyStr()
In A::~A()
In A::~A()
Clearly the destructor runs twice, even if there is only one object that is created. How is this possible?
Note: I am using gcc 7.3.0 on 64-bit linux.
Upvotes: 1
Views: 1961
Reputation: 275370
Double delete is undefined behaviour.
Undefined behaviour doesn't guarantee a runtime exception; that would be defined. Undefined behaviour means anything can happen. This can include time travel, formatting harddrives, emailing browser history to your contacts, or nothing at all.
I have yet to experience browser history being emailed, that I know of. I have experienced the rest.
Upvotes: 7
Reputation: 2941
If at some point prior to the unique_ptr instance going out of scope you decide you want to delete the managed object, just do unique_ptr_instance.reset(nullptr)
. This calls the deleter and causes the managed object to become nullptr, deleting which when the instance finally goes out of scope is a no-op.
Upvotes: 0