10
void changeString(const char* &s){
    std::string str(s);
    str.replace(0, 5, "Howdy");
    s = str.c_str();
}

int main() {
    const char *s = "Hello, world!";
    changeString(s);
    std::cout << s << "\n";
    return 0;
}

When I run this code, it prints "Howdy, world!" I would think that str gets destroyed when changeString exits. Am I missing something with the way std::string gets allocated?

user2871915
  • 469
  • 7
  • 17
  • I *guess* this *happened* to work. – MikeCAT Mar 12 '16 at 16:13
  • Sometimes undefined behavior appears to work. You shouldn't ever expect this to work, however. – Gary Jackson Mar 12 '16 at 16:26
  • Bad luck. You're right that it's wrong. – Pete Becker Mar 12 '16 at 16:49
  • You don't do anything that would re-allocate and overwrite the deleted chunk in before you use that chunk and implementations rarely invalidated deleted-chunks by returning them to the system, so your example is quite likely to happen to work, but it's undefined behavior nonetheless. You should `return` the string. – Petr Skocik Mar 12 '16 at 16:59
  • I want to tell you to use appropriate tools, but none of [ASan](http://clang.llvm.org/docs/AddressSanitizer.html), [UBSan](http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html), gdb or [cppcheck](http://cppcheck.sourceforge.net/) catch anything. How sad. – nwp Mar 13 '16 at 01:20

2 Answers2

14

Yes, str is destroyed; but the memory of the string isn't cleared; your "s" pointer point to a free but non cleared memory. Very dangerous.

max66
  • 65,235
  • 10
  • 71
  • 111
14

It's undefined behaviour when std::cout << s tries to access the pointer, because the destructor of the local std::string in changeString has freed the memory which the pointer still points to.

Your compiler is not required to diagnose the error but can instead generate a binary which can then do whatever it wants to.

The fact that you got the desired output was just bad luck because it made you think that your code was correct. For instance, I've just compiled your code on my machine and got empty output instead. It could also have crashed, or it may have done other, unrelated things.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62