0

Is this code ok? I know that the reference counter is getting down to zero after the function returns, so the memory should be freed. But it works and prints the dereference successfully outside the function.

Can someone please explain if what I am trying to do is wrong or not, and why? Thanks

#include <iostream>
#include <memory>
#include <string>

std::string& get_string(bool en)
{ 
  return *std::make_shared<std::string>("hello world");
}

int main () {
  auto& my_str = get_string(true);
  std::cout << "str=" << my_str <<std::endl;
  return 0;
}

output:

> ./main
str=hello world
  • 7
    Welcome to the wonderful world of [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior). Just because something seems to work doesn't mean it's actually correct. – Some programmer dude Oct 29 '19 at 12:04
  • it doesn't work: `main` expects to print a valid string. Instead, it just prints something that coincidentally looks like a valid string at THIS moment on YOUR system. Do you get any warnings from the compiler? – Zdeslav Vojkovic Oct 29 '19 at 12:05
  • Just does not expect that this always works... – João Paulo Oct 29 '19 at 12:09
  • _Is this code ok?_ No. No, it's very bad. – Eljay Oct 29 '19 at 12:21

2 Answers2

3

Once you return from get_string, your temporary shared pointer will be destroyed and so will be the std::string inside it. So you are using a dangling reference, which invokes undefined behaviour.

Answered in detail here.

Because of undefined behaviour, the program might execute as expected, but it could also do whatever it wants as well.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
eike
  • 1,314
  • 7
  • 18
0

What you have done is invoking undefined behaviour. The object the reference once referred to already is destroyed and doesn't exist any more.

so the memory should be freed

Well, yes, the memory has been freed. But that doesn't necessarily mean that the process returned the memory to the OS (which would usually make it unaccessible for the process), instead the process might still keep it for re-use and 'free' would then simply mean 'available for re-use' (actually, that happens pretty often, as OS usually assigns memory to processes in larger chunks).

If you create a new string object chances are that the memory gets re-used and you might see the referenced string (that ceased to exist!) suddenly change unpredictably.

Aconcagua
  • 24,880
  • 4
  • 34
  • 59