-1

There is a program in C:

void bar(char *str) {
   str = "ok bye!";
}

int main(int argc, char *argv[]) {
   char *str = "hello world!";
   bar(str);
   printf("%s\n", str); 
   return EXIT_SUCCESS;
}

However, it says that the value str in main method would not be effected by the bar method, but why is that? My understanding is that char *str = "hello world!"; this code makes the pointer str points to the string "hello world". And then bar(str); makes the str pointer points to the string "ok bye!". But why the result is still "hello world"?

void bar(char **str_ptr) {
    *str_ptr = "ok bye!";
}

The solution is to change the parameter of the bar method to a double pointer, why to do that?

xunmiw
  • 7
  • 2
  • 3
    There's a whole [library of books](https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) that can help you answer this particular quandary. Hint: What is different between `str = x` and `*str = x`? What happens at the assembly/machine instruction level? – tadman Mar 20 '20 at 21:05
  • 4
    Ask yourself the same question without pointers being involved. Given `void bar(int x) { x = 42; }`, do you expect that `y = 0; bar(y);` would change the value of `y`? – jamesdlin Mar 20 '20 at 21:06
  • 2
    @jamesdlin An even cleaner code to make a point would be calling `bar(24)`. Now it's clear that there's no variable there to take `42` back into `main`. – Sergey Kalinichenko Mar 20 '20 at 21:09
  • The code is very dangerous and has undefined behavior because `str` in main is actually a `const char *`. You are not allowed to change the memory where it refers to. Please look at https://stackoverflow.com/questions/480555/modifying-c-string-constants So, first you should change `char *str = "hello world!";` to `char str[] = "hello world!";` – MiCo Mar 20 '20 at 21:09
  • You have two completely different variables both called `str`. That makes you think changing one should change the other. If you gave them different names, it would be much clearer. – David Schwartz Mar 20 '20 at 21:16
  • A few links that may help. [Difference between char *pp and (char*) p?](https://stackoverflow.com/questions/60518115/difference-between-char-pp-and-char-p/60519053#60519053) and [Pointer to pointer of structs indexing out of bounds(?)...](https://stackoverflow.com/a/60639540/3422102) – David C. Rankin Mar 20 '20 at 21:29

1 Answers1

0

The str pointer in the function bar is only a local variable. You do not change the str variable in the main code with this. This concept referred to as call-by-value. But since you actually want to change the memory where it points to you can change it. Please pay attention that you do not overwrite the length of the allocated memory.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void bar(char *str, size_t s) {
   strncpy(str, "ok bye!", s);
   str[s-1] = '\0'; // terminate for the case that the string was cropped
}

int main(int argc, char *argv[]) {
   char str[20] = "hello world!";
   printf("%s\n", str); 
   bar(str, sizeof(str));
   printf("%s\n", str); 
   return EXIT_SUCCESS;
}
MiCo
  • 399
  • 2
  • 6