Whats wrong with that?
Why cant i change buf?
I know it works with an array buf[] but why wouldnt it work with a pointer?
Code:char * buf="aaaaaaaaaaaaaaaaaa"; strcpy(buf,"bbbbb"); cout<<buf;
Whats wrong with that?
Why cant i change buf?
I know it works with an array buf[] but why wouldnt it work with a pointer?
Code:char * buf="aaaaaaaaaaaaaaaaaa"; strcpy(buf,"bbbbb"); cout<<buf;
Using Windows 10 with Code Blocks and MingW.
Because this pointer points to the first character of a string literal, and you are not allowed to modify a string literal.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
And ain't THAT a hell of a note, right Ducky??
Been there. I have an old compiler that DOES allow it, and then got a newer one, and it DID NOT allow it.
Thank you Laserlight but im still confused because sometimes you can modify it.
I just need to find that other example... (or maybe im just mixing up something)
@Adak yes its very frustrating...
Last edited by Ducky; 07-23-2010 at 04:25 AM.
Using Windows 10 with Code Blocks and MingW.
maybe you want
You can change buff, when it's declared as an array.Code:char buff[]={"aaaaaaaaaaaaaaaaaaaaaaaaaaa"};
When you have this:
... the variable buf is on the stack and contains the address of the string literal "aaaaaaaaaaaaaaaaaa". This string literal is placed in an area of memory that's considered to be read-only. That is, you are not meant to write to it. The danger of writing to that memory location it is that the amount of memory the string literal is to take in the code is set when you compile the program. Other values may be placed adjacent to this string literal. If you were to then try and write to this location you could end up mistakenly writing more to this location than should be allowed which could potentially screw up lots of other values being stored nearby. Therefore, these regions of memory are usually marked as read-only. Attempting to strcpy data to this location represents an attempt to write to this read-only area and is not allowed (usually results is a run-time error).Code:char * buf="aaaaaaaaaaaaaaaaaa"; strcpy(buf,"bbbbb"); cout<<buf;
Syntactically the strcpy statement is correct as written and so it doesn't result in a compilation error but rather the aforementioned run-time error. This is usually the result of inexperienced programmers not knowing how to properly consider such things as pointers to string literals. What should have been done in this case (what experienced programmers would have done) is to have made the pointer a pointer to const char instead of just a straight pointer to char. In this case you would have the following:
... the above code would result in a compile time error which would have let you know you were attempting to do something dangerous/stupid and that you need to rethink things a little bit.Code:const char * buf="aaaaaaaaaaaaaaaaaa"; strcpy(buf,"bbbbb"); cout<<buf;
I think I've answered the "what's wrong" and the "why can't I" parts. Now for the "why it works for []" part. When you have the following:Originally Posted by Ducky
... the variable buf exists on the stack as before but now it is an array of characters instead of a pointer to a string literal. The array on the stack is sized as appropriate to hold all the characters in the initialization string (plus the null terminating char) and said string literal is copied into that memory location. The memory on the stack is writable and so the subsequent strcpy function call will work correctly when you overwrite the first few characters with "bbbbb". There is still a danger in the above code that you can still write more to the location than is safe to do so if you are not careful.Code:char buf[]="aaaaaaaaaaaaaaaaaa"; strcpy(buf,"bbbbb"); cout<<buf;
"Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
-Christopher Hitchens
I agree that casts can be evil, but even without one, I can get my compiler to produce an executable (granted, it does issue a warning), which then segfaults when run.
I have nothing against const qualifying a string literal. I do think newcomers to C sometimes will be misled by the idea of 'const' though, thinking that by qualifying a symbolic identifier (i.e, a variable name) as const, they somehow wrap a cloak of protection around the contents of the variable, making it immutable by any means.
C's philosophy is not about preventing one to trip on his toes.but rather about the liberty of doing it. With great freedom comes great responsibility.
1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
3. Get rid of conio.h and other antiquated DOS crap headers.
4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.
C lacks too many constructs that allows one to do many things safely and easily without sacrificing either flexibility or freedom.
While flexibility and freedom is good, it is bad when utilized the wrong way and we do that way too often, increasing bugs and frustration.
If there are means to explicitly disallow certain things, then they should not easily be circumvented. If they are, then what is the point of them?
Even in C though sidestepping const is hardly done. I think what people frequently misunderstand is what is constant.
foo *bar;
const foo *bar;
const foo *const bar;
All those are different levels of constant-ness. The cloak of protection is actual protection, unless you consider passing non-const arguments to a function that treats them as const to be wrong (as C++'s type system does).
Don't bring cpp arguments to a C reunion
C is simply a language that assumes a certain level of maturity from the programmer, it won't be a programmer babysitter. C lacks a lot of things specifically because the idea of it is to be as non presumptuous as possible. This is also while it is still pretty heavily in use today.
1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
3. Get rid of conio.h and other antiquated DOS crap headers.
4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.