1
void func(const char *s){
    char *result = new char[strlen(s)];
    strcpy(result, "new stuff");
    s = result;    
}

int main(){
    const char *str = "old stuff";
    func(str);
    std::cout << str << "\n";
    return 0; 
}

The code above compiles without fuss, but str is not changed (still prints out "old stuff"). Why is this? As far as I know, str should be passed by reference into the function, and I should be able to reassign a const char * to point to something else.

user2871915
  • 469
  • 7
  • 17
  • Hint: It is passed by value. – 3442 Mar 11 '16 at 19:54
  • *As far as I know, str should be passed by reference into the function* how would it be passed by reference, its not a reference – Borgleader Mar 11 '16 at 19:55
  • Possible duplicate of [What's the difference between passing by reference vs. passing by value?](http://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value) – owacoder Mar 11 '16 at 19:56
  • well, that was silly. dumb question, thanks for the sanity check. – user2871915 Mar 11 '16 at 19:58
  • Note that result* is not large enough to contain "new stuff", so UB. – Martin James Mar 11 '16 at 19:58
  • 1. Don't use C strings if you do not have to. 2, Do not forget `'\0'` at the end of the string constants. 3. Don't forget to `delete[]` memory which has been allocated using `new[]`. – Pixelchemist Mar 11 '16 at 20:00

2 Answers2

3

The code above compiles without fuss

This is expected, because you are not doing anything out of the ordinary (apart from leaking memory, of course).

but str is not changed (still prints out "old stuff"). Why is this?

This is because s of func is a copy of str pointer from main. Re-assigning this pointer makes what used to be a copy point to some other location; the original remains unchanged, though.

As far as I know, str should be passed by reference into the function, and I should be able to reassign a const char * to point to something else.

Nothing is passed by reference implicitly; you must specify that a function takes its argument by reference, otherwise it's passed by value. This includes pointers.

The fix required to make your function do what you expect is very small: add an ampersand in front of s.

void func(const char *&s){
    // Don't forget to add 1 for null terminator
    char *result = new char[strlen(s)+1];
    strcpy(result, "new stuff");
    s = result;    
}

Demo.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1
void func(const char *s){
    char *result = new char[strlen(s)];
    strcpy(result, "new stuff");
    s = result;    
}

it is not changed because s is local copy of original pointer which caller passed from main. Just it is pointing to same address as original pointer. So when you are doing this assignment, only the value of local copy gets changed.

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90