std::shared_ptr<std::string> test() {
return std::make_shared<std::string>("sdsd");
}
cout << *test() << endl;
The above code works. Can someone please let me know where is the "sdsd" string stored. I was expecting it to error out as rvalue is a temporary object. Where is the rvalue copied to and stored in?
With weak_ptr
std::weak_ptr<std::string> test() {
return std::make_shared<std::string>("sdsd");
}
cout << *test().lock() << endl;
Interestingly the above code errors out. What's the difference?
CodePudding user response:
In
std::shared_ptr<std::string> test() {
return std::make_shared<std::string>("sdsd");
}
the constructed shared_ptr
is returned and lives on as a temporary variable long enough to be used by the caller before going out of scope and freeing the string
allocated by make_shared
.
The "sdsd" string
is stored in dynamic storage owned by the returned shared_ptr
.
In
std::weak_ptr<std::string> test() {
return std::make_shared<std::string>("sdsd");
}
the shared_ptr
wasn't returned and went out of scope, taking the string
allocated by make_shared
with it. Since this was the only existing copy of the shared_ptr
this leaves the returned temporaty weak_ptr
variable connected to an expired share_ptr
. If you test the return value of lock
you'll see it's a default-constructed shared_ptr
holding a null pointer.
Documentation for std::weak_ptr::lock
.
The "sdsd" string
isn't stored anywhere after test
returns. It departed when the shared_ptr
that owned it went out of scope.
CodePudding user response:
The above code works. Can someone please let me know where is the "sdsd" string stored. I was expecting it to error out as rvalue is a temporary object. Where is the rvalue copied to and stored in?
The memory was allocated in the call to make_shared
.
Interestingly the above code errors out. What's the difference?
The difference is that the lock
operation on a weak_ptr
can fail if there does not exist at least one shared_ptr
to the object. That's the purpose of weak_ptr
-- to allow the object to be freed and access it only if it still exists.