Reputation: 15
This seems like it should be easy but i've spent way too much time on it. Hopefully someone can help.
char *string_labels[5] = { "one", "two", "three", "four", "five" };
void myFunction(void)
{
//can print them just like expected
for(i=0; i < 5; i++)
{
printf("%s\n", string_labels[i]);
}
//how can i change the contents of one of the elements??
sprintf(string_labels[0], "xxx"); <-crashes
}
Upvotes: 1
Views: 424
Reputation: 123468
Each of string_labels[i]
points to a string literal, and attempting to modify the contents of a string literal invokes undefined behavior.
You'll need to declare string_labels
as an array of arrays of char
, rather than as an array of pointers to char
:
#define MAX_LABEL_LEN ... // however big the label can get + 0 terminator
char string_labels[][MAX_LABEL_LEN]={"one", "two", "three", "four", "five"};
This declares a 5-element array (size taken from the number of initializers) of MAX_LABEL_LEN
arrays of char
. Now you can write to the contents of string_labels[i]
.
Upvotes: 0
Reputation: 455030
string_labels
is an array of char pointers pointing to string literals. Since the string literals are read-only, any attempt to modify them leads to undefined behavior.
You can change the declaration of string_labels
as below to make your sprintf
work:
char string_labels[][6] = { "one", "two", "three", "four", "five" };
Upvotes: 0
Reputation: 399833
To do this, you need to use a character array, so that you actually have some runtime-writable space to modify:
char string_labels[][20] = { "one", "two", "three", "four", "five" };
void myFunction(void)
{
/* Printing works like before (could be improved, '5' is nasty). */
for(i=0; i < 5; i++)
{
printf("%s\n", string_labels[i]);
}
/* Now, modifying works too (could be improved, use snprintf() for instance. */
sprintf(string_labels[0], "xxx");
}
Upvotes: 2
Reputation: 14870
It crashes because it's in read-only memory. Try
char string_labels[][6] = { "one", "two", "three", "four", "five" };
sprintf(string_labels[0], "xxx");
Upvotes: 3