Http://stackoverflow.com/questions/3228664/why-am-i-able-to-change-the-contents-of-const-char-ptr
I passed a pointer to ptr
a function whose prototype takes it as const
.
foo( const char *str );
Which according to my understanding means, that it'll is not being able to change the contents of ptr
passed. Like in the case of foo( const int i )
. If foo()
tries i
to chnage the value of, compiler gives error.
But here I see that it can change the contents of ptr
easily.
Please be a look at the following code
Foo( Const Char *Str){strcpy(Str, "ABC" ) ;Printf( "%s ():%s\n" ,__func__,Str) ;}Main(){ CharPtr[ ] = "Its just to fill the space" ;Printf( "%s ():%s\n" , __func__ , ptr ; ( const ptr ) ; Printf ( , __func__ ptr ) ;return; /span>
On compilation, I only get a warning, no error:
warning: passing argument 1 of ‘strcpy’ discards qualifiers from pointer target type
And when I run it, I get an output instead ofSegmentation Fault
Main (): its just to fill the space
Foo (): ABC
Main (): ABC
Now, my questions is
1- What does in const char *str
prototype actually means?
Does this mean which function cannot change the contents of str
? If that's so what come the above program changes the value?
2- How can I make sure, the contents of the pointer I have passed won't be changed?
From ' contents of the pointer ' in the above stated question, I mean ' contents of the memory pointed at by the pointer ', no T "address contained in the pointer".
Edit
Most replies say the This is because of and strcpy
C implicit type conversion. But now I tried this
foo ( const char *str ) { str = "Tim" ;//strcpy (str, "ABC"); Printf ( "%s ():%s\n" Span class= "pun" >, __func__ , str ) ; /span>
This time the output was, with no warning from compiler
Main (): its just to fill the space
Foo (): Tim
Main (): its just to fill the space
So apparently, memory pointed-to-be changed to the memory-location containing and its in str
"Tim"
foo()
. Although I didn ' t use this time strcpy()
.
Is isn't const
supposed to stop this? Or my understanding is wrong?
To me it seems this even const
with, I can change the memory reference and the contents of memory reference too. What's the use?
Can you give me a example where complier would give me error that I am trying to change a const pointer?
Thanks to all of your for your time and effort.
Your understanding is correct, are const char*
a contract that means your can ' t change memory through this particular pointer.
The problem is, and is, very lax with type conversions. strcpy
takes a pointer to Non-const Char, and it's implicitly converted from const char*
to char*
(as compiler Helpfully tells you). You could as easily pass an integer instead of pointer. As a result, your function can ' t change content pointed ptr
by, but strcpy
can, because it sees a non-const pointer. You don't get a crash, because in your case, the pointer points to an actual buffer of sufficient size, not a read-only St Ring literal.
To avoid this, the look for compiler warnings, or compile, for example, and with -Wall -Werror
(if is using GCC).
This behaviour are specific to C. C + +, for example, does not allow, and requires an explicit cast (C-style cast or a c0/>) to strip const
qualifier, as you would reasonably expect.
Answer to the extended question
Assigning a string literal into a non-const char, which, unfortunately, was legal in C and even c++! It is implicitly converted char*
to, even though writing through this pointer would now result in undefined behaviour. It is a deprecated-feature, and only c++0x so far does does allow this to happen.
With the-said, in order-to-stop changing the pointer itself, you had to declare it as const pointer to char ( ). Or, if you want to make it both the contents pointed by it and the pointer itself don ' t change, use a const pointer T o const char ( const char * const
).
Examples:
voidFoo( Char *A, Const Char *B, Char *ConstC, Const Char *ConstD) { CharBuf[10];A=Buf; /* OK, changing the pointer */ *A= A; /* OK, changing contents pointed by pointer */B=Buf; /* OK, changing the pointer */ *B= ' B '; /* error, changing contents pointed by pointer */ C = Buf;/* error, changing pointer */ *c = ' C ' ; /* OK, changing contents pointed by pointer */ D = Buf; /* error, changing pointer */ *d = ' d ' ;/* error, changing contents pointed by pointer */}
For all error lines GCC gives me "error:assignment of read-only".
Why am I able to change the contents of const char *PTR?