tags:

views:

1128

answers:

8

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?

+1  A: 

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.

Joel Coehoorn
string literals allocated on the stack? er... They are allocated in the data section.
Serge - appTranslator
+21  A: 

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.

Michael Burr
I did a test, however. I assigned str to a string and printed out the string and it's memory address. Then, I assigned str to another string and again, printed out the string and it's memory address. The string literal had changed but the address had not.
Chris
Did you print out the address of the pointer, or the address to which the pointer points?
mipadi
@Chris - post your test code please. Thanks!
Parappa
Thanks everyone. Yes, I was printing out the address of the pointer, not the data! What threw me off in this problem is how C deals with string literals. You can assign a string literal to a char* but you can't assign an integer to an int* in the same way, for example.
Chris
@Chris: that's because a string literal is actually a char[], which can be implicitly converted to a pointer to its first element
Christoph
Ok that makes sense. Thanks!
Chris
A: 

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.

Rob Segal
A: 

It's been a while, but I believe, the above code is a pointer to a 'const char'. If I understand you correctly, you want a constant pointer to a 'char'.

Try this

char const * str = "test";
John MacIntyre
+6  A: 

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.

Matthew Crumley
Someone could cast away the const if they were really determined, but if the compiler places the chars in a read-only page then modifying them will cause a fault at runtime.
marklam
Technically the compiler and linker together. Switches depend on the tools you're using.
marklam
+3  A: 

Related: http://stackoverflow.com/questions/162480/const-in-c

Ates Goral
A: 

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

Kieran Tully
+1  A: 

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.

Anthony Cuozzo