1

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

}
3
  • so is this declaration the same as const char *string_labels = { "one", "two", "three", "four", "five" }; ? I thought if it wasn't declared const it would be changeable? Can you explain why? Thanks for helping Commented Nov 11, 2010 at 15:02
  • Yes, string literals are effectively const, even if they aren't declared as such. Typically they reside in a read-only segment. Commented Nov 11, 2010 at 15:06
  • In C, string literals are sequences of char, but are read only. Unfortunately this leads to a lot of confusion. If you are using GCC try using -Wwrite-strings. Commented Nov 11, 2010 at 15:08

4 Answers 4

3

It crashes because it's in read-only memory. Try

char string_labels[][6] = { "one", "two", "three", "four", "five" };
sprintf(string_labels[0], "xxx");
Sign up to request clarification or add additional context in comments.

Comments

2

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");
}

Comments

0

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" };

Comments

0

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].

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.