5

I have the following code:

using namespace std;
vector<string*> v;
{
  string s = "hello";
  v.push_back(&s);
}
{
  string ss = "goodbye";
  v.push_back(&ss);
}

cout << v.at(0)->c_str() << endl;
cout << v.at(1)->c_str() << endl;

which prints

goodbye
goodbye

if I remove the scope parenthesis the code will print

hello
goodbye

What exactly happens when I leave the first scope, that the pointer to the first string now points to the second one?

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
Bg1987
  • 1,129
  • 1
  • 11
  • 25
  • 1
    UB, Luke! This is just UB. You got lucky that your computer did not explode. –  Jan 09 '12 at 15:52
  • 1
    May I refer you to the now famous answer to this question: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – Benj Jan 09 '12 at 16:03
  • Yup, [crossing the streams](http://en.wikipedia.org/wiki/Proton_pack#Crossing_the_Streams) again. – Fred Larson Jan 09 '12 at 16:15
  • @benj: thanks for linking that. Great read. – JoeFish Jan 09 '12 at 16:55

4 Answers4

7

The stored pointers become dangling pointers after the scope and any attempt to read what they point to yields undefined behavior.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
  • that was what I thought should happen, but the fact that the results were constant I had to ask. – Bg1987 Jan 09 '12 at 15:53
  • 2
    undefined behavior means anything can happen, including getting normal looking, consistent results. This is one of the reasons undefined behavior is so bad; you might not even notice it when you write a program, but your program may fail catastrophically in some other circumstances. – bames53 Jan 09 '12 at 15:58
  • @Bg1987: Undefined behavior does not mean random behavior. True randomness does not really exist :) It means that what will happen is not bound by any rule (from the Standard point of view), but the output of the compiler is still bound by the code production rules of the compiler, so the range of behaviors it can provide is limited. – Matthieu M. Jan 09 '12 at 15:59
  • @MatthieuM. But not very. The most frequent manifestation of undefined behavior is that the code works perfectly with all of your tests, but fails spectacularly in the demo in front of the most important client. Or when you insert a totally unrelated line in a completely different place in the code. Or when you change the compiler options, or get a bug fix for the compiler. – James Kanze Jan 09 '12 at 18:26
3

What happens there is an undefined behavior, since s is out of scope at the time you referenced it in the call to cout<< operator.

It does not crash because s and ss happen to have the same address with your specific architecture and the implementation of C++. In other words, others who try replicating your experiment on other architectures or with other compilers would probably get different results.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

In practice the system is reusing the memory it used for the string s to hold the string ss. But this just happens to be how the compiler is managing the memory; according to the C++ standard you can't rely on any such behavior and the actual outcome of the code you've posted is undefined.

Paul Eastlund
  • 6,713
  • 4
  • 18
  • 20
2

You are dereferencing two pointers to two objects that have been destroyed: this is undefined behaviour. Anything could happen here.

hmjd
  • 120,187
  • 20
  • 207
  • 252