30
votes

Why does the following code in C work?

const char* str = NULL;
str = "test";
str = "test2";

Since str is a pointer to a constant character, why are we allowed to assign it different string literals? Further, how can we protect str from being modified? It seems like this could be a problem if, for example, we later assigned str to a longer string which ended up writing over another portion of memory.

I should add that in my test, I printed out the memory address of str before and after each of my assignments and it never changed. So, although str is a pointer to a const char, the memory is actually being modified. I wondered if perhaps this is a legacy issue with C?

6
I'd guess that you were actually printing out the address of the str variable, which doesn't change, its value changes.Greg Rogers

6 Answers

43
votes

You are changing the pointer, which is not const (the thing it's pointing to is const).

If you want the pointer itself to be const, the declaration would look like:

char * const str = "something";

or

char const * const str = "something";  // a const pointer to const char
const char * const str = "something";  //    same thing

Const pointers to non-const data are usually a less useful construct than pointer-to-const.

13
votes

Further, how can we protect str from being modified?

char * const str1; // str1 cannot be modified, but the character pointed to can
const char * str2; // str1 can be modified, but the character pointed to cannot
const char * const str3 // neither str3 nor the character pointed to can be modified.

The easiest way to read this is to start from the variable name and read to the left:

  • str1 is a constant pointer to a character
  • str2 is a pointer to a character constant
  • str3 is a constant pointer to a character constant

NOTE: the right-to-left reading does not work in the general case, but for simple declarations it's a simple way to do it. I found a java applet based on code from "The C Programming Language" that can decipher declarations with a full explanation of how to do it.

2
votes

On a related note, definitely take a look at "const pointer versus pointer to const". It helps with what some people call const correctness. I keep it in my bookmarks so that I can refer to it every now and then.

1
votes

What you're looking for may be the syntax...

const char* const str = NULL;
str = "test";
str = "test2";

Notice the "const" after the char* which yields a compiler error when trying to compile/build.

1
votes

Memory for the string literals are allocated on the stack, and all your assignments do are change the str pointer to point to those memory addresses. The constant character it pointed to initially hasn't changed at all.

1
votes

Besides, declaring a variable as const means that variable is read-only; it does not mean the value is constant!