Difference of representing constant char array using char* and char[] in C

19,797

If you wish to maximize the chances that your const arrays will be placed into actual read-only memory, you should make them static as well:

static const char c[] = "abcdef";

This is because all variables with automatic storage duration are normally created in the same area of memory, regardless of whether they are const-qualified or not. This area of memory therefore cannot be made read-only.

However, given that your implementation apparently doesn't place string literals into read-only memory either, it may not use read-only memory at all and the warning might be the best you can hope for. If you are using a gcc-based compiler, you could also try the -fno-writable-strings compiler option.


The reason that these two lines are errors:

a = "overwrited";
c = "overwrited";

is because a and c are arrays, and arrays cannot be directly assigned to with the = operator (regardless of whether they are const or not). The = in the variable declaration is not an = operator - it's just part of the initialisation syntax, and arrays can be initialised.

The reason that these lines are OK:

b = "overwrited";
d = "overwrited";

is because b and d are non-constant pointers to constant chars. These assignments don't mutate the original strings that b and d pointed to - they change b and d to point to different strings (possibly the same string, actually).

If you want b and d to be constant pointers (so that the pointer itself cannot be changed), you can change the declarations:

char * const b = "abcdef";
const char * const d = "abcdef";

..and the assignments to b and d should at least issue an error message from the compiler.

Share:
19,797
Erencie
Author by

Erencie

Updated on June 29, 2022

Comments

  • Erencie
    Erencie almost 2 years

    What is a good way of creating a constant string in C? A string that cannot be mutated by doing character assignment to one of its indexed location. And a string that cannot be replaced by another string in later execution after initialization.

    I tried both char* and char[] in the following code. I tried them with and without the "const" keywords. The outcome is very bizarre.

    The following is my code:

    #include <stdio.h>
    main() {
        char a []= "abc" "def";
        char* b = "abcdef";
        const char c [] = "abcdef";
        const char* d = "abcdef";
    
        a[1] = 'y';
        b[1] = 'y';
        c[1] = 'y';
        d[1] = 'y';
        printf("%s %s %s %s \n", a, b, c, d);
    
        a = "overwrited";
        b = "overwrited";
        c = "overwrited";
        d = "overwrited";
        printf("%s %s %s %s \n", a, b, c, d);
    }
    

    The result is that In the first printf, all a, b, c, d can be mutated; but c and d appear warnings that "assignment of read-only location". In the second printf, both a and c return error. But b and d are smoothly replaced by another string and become "ovewrited".

    I am very confused by this result that it seems like "const" keyword doesn't have the effect on doing string assignment; but it has effect on indexed character mutation. And char[] and char* show different behaviours as well. Could someone explain to me the mechanism behind this?