0

I am new to C++. Can someone please let me know what is wrong with the following code segment -

class Person {
   public:
      const std::string& name;

      Person(const std::string& s): name(s) {}
      void dump(void) const {
         cout << name << endl;
         //cout << &name << endl;
      }

};


std::map<std::string, std::shared_ptr<Person>> plist;

std::string namestr = "Hoo";
std::shared_ptr<Person> r1(std::make_shared<Person>("Dull"));
plist.insert({"Key1", r1});
auto u = plist.find("Key1");
shared_ptr<Person> v = u->second;
v->dump();
plist.erase(plist.find("Key1"));

My intention is to create a database of Person objects and I was trying to use shared_ptr for that.

v->dump() causes a segmentation fault. However, if I use the 'namestr' variable instead of the string literal "Dull" then the v->dump() appears to work correctly, i.e. the following -

std::shared_ptr<Person> r1(std::make_shared<Person>(namestr));

Also, the following way also seems to work even though I use a string literal in the intializer.

std::shared_ptr<Person> r1(new Person("Dull"));

Pointers to the mistake I am making would be much appreciated!

Jai Prabhu
  • 245
  • 3
  • 10

1 Answers1

1
class Person {
   public:
      const std::string& name;

      Person(const std::string& s): name(s) {}
      void dump(void) const {
         cout << name << endl;
         //cout << &name << endl;
      }

};

this is storing a reference to a string whose life time is not guaranteed. You should do

class Person {
   public:
      const std::string name;

      Person(const std::string& s): name(s) {}
      void dump(void) const {
         cout << name << endl;
         //cout << &name << endl;
      }

};

You code fails because "Dull" created a temporary string that went out of scope immediately

pm100
  • 48,078
  • 23
  • 82
  • 145
  • Why did you remove the `const`? – Lightness Races in Orbit Feb 23 '17 at 01:17
  • Thanks a lot for the response. That does make sense. What I was wondering was why does the following form *seem* work - std::shared_ptr r1(new Person("Dull")); – Jai Prabhu Feb 23 '17 at 01:22
  • because you have not tried to access anything that has disappeared yet. While that line is executing `std::string("Dull")` exists and you can create a reference to it. After the line executes "dull" disappears so the ref (`name`) is invalid. Things go bad when you try to use that reference – pm100 Feb 23 '17 at 01:48
  • @LightnessRacesinOrbit `shamefaced` - cos i could not remember if the const rules for ref vs 'copy' were different and rather than try it I chickened out and dropped the `const` - since its not relevant to the OP problem – pm100 Feb 23 '17 at 01:50