1

Very simple question, which most likely calls for an explanation on how references work and why my understanding is flawed.

Given the simple code snippet below:

#include <iostream>
#include <string>

struct Foo
{
    std::string &ref;
    Foo(std::string &bar) : ref(bar) { }
};

int main()
{
    std::string s1 = "foo1";
    Foo f(s1);
    f.ref[0] = 'b';
    std::cout << s1 << std::endl; // prints boo1
    {
        std::string f2("tmp");
        f.ref = f2;
    } 
    // shouldn't f.ref be dangling by now?
    std::cout << f.ref; // prints tmp
}

Output: 

My understanding is that f2 will be destroyed at the end of that block, thus f.ref will be a dangling reference. What is really going on?

omzy
  • 93
  • 1
  • 10
  • Do you think f is still valid? Does std::string have an assignment operator? What does s1 hold at the end? – Stephen M. Webb May 01 '20 at 02:18
  • See [Why are references not reseatable in C++](https://stackoverflow.com/questions/728233/why-are-references-not-reseatable-in-c) – dxiv May 01 '20 at 02:19
  • Yeah just realized that and pulled the comment out. I was off thinking like it was a pointer. – Delta_G May 01 '20 at 02:19
  • Not fully a dupe because of your references, but relevant to your thinking: [Can a local variable's memory be accessed outside its scope?](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) (Even if you had a dangling reference, your program would not be guaranteed to malfunction.) – JaMiT May 01 '20 at 02:32

1 Answers1

3

f.ref = f2 is the same as s1 = s2, because f.ref and s1 are both names for the same string object.

Perhaps you are mixing up the concepts of initialization of a reference, and assignment of objects. A reference can only be initialized once (and in fact, must be initialized on creation).

In the initialization ref(bar), ref is initialized to refer to the same object bar refers to (which is also the same object as is called s1).

In the assignment expression f.ref = f2; the assignment operator is called for the object which f.ref names.

M.M
  • 138,810
  • 21
  • 208
  • 365