Search code examples
carraysstringstring-literals

The difference between `char *str` and `char str[]` in the declaration of a string


I have the following function in C:

int TransMinMaj(char *c)
{
    if((*c) >= 'a' && (*c) <= 'z')
    {
        *c += 'A' - 'a';
        return 1;
    }
    else if((*c) >= 'A' && (*c) <= 'Z')
        return 1;
    return 0;

}

As you can see, this function:
1. Return 1 if the character tested is a letter
2. Transform the lower case to upper case
3. Otherwise, return 0 (to indicate that it is not a letter)

I have chosen to pass the parameter by address because I want to change the value of the passed parameter c in the memory.

Now my question comes: I tested my function withe the following code :

char str[] = "abcdefg";
printf("Before: %s\n", str);    
TransMinMaj(&str[1]);
printf("After: %s\n", str);

Until now, everything is good, no errors, no warnings. And as you can see, in this test, I transforme the lower case letter b (also the second element of the string (array of characters)) to the upper case letter 'B' in the memory.

But, if change the test code a litte bit:

char *str = "abcdefg";
printf("Before: %s\n", str);    
TransMinMaj(&str[1]);
printf("After: %s\n", str);

There is a segmentation error(core dumped). But I don't know why.
So here comes my question:
1. What is the difference between char *str and char str[] in a declaration ?
2. Where does my segmentation error come from?


Solution

  • char str[] = "abcdefg";
    

    and

    char *str = "abcdefg";
    

    are two different things.

    • The first one is an array, initialized with "abcdefg".

    • The second one is a pointer pointing to the string literal "abcdefg".

    In the second case, when you attempt to modify the string literal, you invoke undefined behavior, as any attempt to modify a string literal is UB.