The following code passes to the function modify_entry
a pointer to an object of type Entry
and inside the body of the function a unique_ptr
adopts the raw pointer. However, the object to which the pointers point seems to live on after the function returns.
When I compile this code
#include <iostream>
#include <memory>
struct Entry {
Entry(std::string name) : name_(name) { std::cout << "Constructor for " + name_ + '\n'; }
~Entry() { std::cout << "Destructor for " + name_ + '\n'; }
std::string name_;
};
void modify_entry(Entry* e_ptr){
std::cout << "Inside modify_entry()\n";
std::unique_ptr<Entry>{e_ptr}->name_ += " Doe";
}
int main(int argc, const char * argv[])
{
Entry* entry_ptr = new Entry("John");
modify_entry(entry_ptr);
std::cout << "Back from modify_entry()\n";
std::cout << entry_ptr->name_ << '\n'; // <---- line 25
return 0;
}
with
clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
It runs without an error and the output is
Constructor for John
Inside modify_entry()
Destructor for John Doe
Back from modify_entry()
John Doe
Here, however, I get a runtime error because of line 25.
Q: Why isn't there a runtime error when I run the executable generated by clang?
I would really appreciate it if someone could clarify the situation. Please note that I am not trying to properly transfer ownership. This contrived example of bad code is the byproduct of a debugging process. make_unique
and move semantics for unique_ptr
etc are great, but this is not what I am asking.
Thanks in advance.
However, the object to which the pointers point seems to live on after the function returns.
The key thing here is "seems to". Actually, the Entry
's lifetime ends at the end of this line:
std::unique_ptr<Entry>{e_ptr}->name_ += " Doe";
The unique_ptr
has taken ownership of the memory, but the temporary unique_ptr
's lifetime ends at the end of that statement, so it also deletes the Entry
that it owns. Accessing memory that was formerly used by the object is undefined behavior. That it works on some platforms and not others is just the nature of undefined behavior.