Reputation: 1513
I don't have clear idea how the following two pieces of code show different behavior:
code:
#include <stdio.h>
void set(char** addr) {
char* str = "testa";
*addr = str;
}
void _set(char*** addr) {
char* arr[] = {"testb"};
*addr = arr;
}
int main() {
char* a;
set(&a);
printf("'%s'\n", a);
printf("'%s'\n", a);
char** b;
_set(&b);
printf("'%s'\n",b[0]);
printf("'%s'\n",b[0]);
}
Output:
testa
testa
testb
testb
When I remove the first bit, the testa part, the code is:
void _set(char*** addr) {
char* arr[] = {"testb"};
*addr = arr;
}
int main() {
char** b;
_set(&b);
printf("'%s'\n",b[0]);
printf("'%s'\n",b[0]);
}
Output:
'testb'
'UH▒▒AWE1▒AVAUATSH▒▒8▒E▒'
Upvotes: 0
Views: 151
Reputation: 108
You are experiencing memory corruption. Your code in main() referring memory on the stack which will likely be corrupted when a new function is called. "testb" itself isn't corrupted, but arr is (the location containing the address to the string literal "testb")
If you make the following change, it will work:
char* arr[] = {"testb"}; /* Make arr global to fix the bug */
void _set(char*** addr) {
/* alternatively, you could make arr static here, static char* arr... */
*addr = arr;
}
With enough digging, it should be explainable why it works in the first case, but not in the second, and it will be deterministic and repeatable. For example, try this:
void _set(char*** addr) {
char pad[3]; // <-- Insert a 3 byte stack variable
char* arr[] = {"testb"};
*addr = arr;
}
You should see something different now (hmmm, does that second line look familiar?):
'testb'
''%s'
'
Upvotes: 1
Reputation: 94
The seta()
function defines str
as a pointer to a string. The string itself is an array of characters 't','e','s','t','a','\0'
located on the heap.
The _seta()
function defines something completely different: an array of (one) pointers to (one) strings. The array itself is located on the stack, meaning that the array will go out of scope (i.e. get thrashed) as soon as the function returns. The string itself is another array of characters 't','e','s','t','b','\0'
, which is located on the heap, just as above.
Thus: the call _set(&b);
obtains a pointer to undefined memory. The fact that everything seemed to work when you called set(&a);
beforehand, was just pure bad luck.
Upvotes: 0