In C specifically (i suppose this also applies to C++), what is the difference between
char str[4] = "abc";
char *cstr = {"abc"};
Problems arise when i try and pass my “abc” into a function that accepts char**
void f(char** s)
{
fprintf(stderr, "%s", *s);
}
Doing the following yields a compiler error. If cast to char** (to make compiler happy) program seg faults.
f(&str);
However the following works fine
f(&cstr[0]);
This is an example of how pointers and arrays are not equivalent in C. In particular: the rule that arrays decay to pointers is not applied recursively
This means that an array can be used as a pointer, but a pointer-to-array cannot be used as a pointer-to-pointer. This is what you are experiencing here. This is why the compiler complains about mismatched types when you don’t cast &str explicitly to char**. That should be your first clue that something is wrong.
The reason that this causes a segfault is this: The way that an array automatically decays to a pointer is by turning into the address of its first element. A pointer to an array is likewise a pointer to the address of the array’s first element. So a pointer-to-array and array-as-pointer are the same thing. In other words str, when passed as a pointer, has a value identical to &str. So if you try to make &str into a pointer-to-pointer, it doesn’t work, since is just a (single-level) pointer.
For example,
But after that last call to
f((char**)p_str), the value of pp in f is still going to be 0x1234 because you haven’t modified the value of p_str, you’ve only suppressed the type-checker’s complaint. This means that *pp is going to be ‘a’, not a pointer to the address that contains ‘a’. And that’s why you get a segfault when f tries to execute **pp.