Pointer

This is a discussion on Pointer within the C Programming forums, part of the General Programming Boards category; Whats wrong with that? Why cant i change buf? I know it works with an array buf[] but why wouldnt ...

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    803

    Pointer

    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;
    Compiler MSVC++ 2013 with Code::Blocks.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,127
    Because this pointer points to the first character of a string literal, and you are not allowed to modify a string literal.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    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.

  4. #4
    Registered User
    Join Date
    Dec 2007
    Posts
    803
    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 05:25 AM.
    Compiler MSVC++ 2013 with Code::Blocks.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    maybe you want
    Code:
    char buff[]={"aaaaaaaaaaaaaaaaaaaaaaaaaaa"};
    You can change buff, when it's declared as an array.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,901
    Quote Originally Posted by Ducky View Post
    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)
    You cannot modify a string literal. I believe the standard says that they cannot. Not sure about the text, though.
    So mark them a const char* and be done with it. If you need to modify the string, use a buffer.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,528
    Quote Originally Posted by Elysia View Post
    You cannot modify a string literal. I believe the standard says that they cannot. Not sure about the text, though.
    The standard states that an attempt to modify a string literal produces undefined behaviour.


    Quote Originally Posted by Elysia View Post
    So mark them a const char* and be done with it.
    I am not sure this buys you much, given how easy it is to sidestep a const qualification.

  8. #8
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,806
    Quote Originally Posted by Ducky View Post
    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)
    When you have this:
    Code:
    char * buf="aaaaaaaaaaaaaaaaaa";
    strcpy(buf,"bbbbb");
    cout<<buf;
    ... 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).

    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:
    Code:
    const char * buf="aaaaaaaaaaaaaaaaaa";
    strcpy(buf,"bbbbb");
    cout<<buf;
    ... 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.


    Quote Originally Posted by Ducky
    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?
    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:
    Code:
    char buf[]="aaaaaaaaaaaaaaaaaa";
    strcpy(buf,"bbbbb");
    cout<<buf;
    ... 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.
    "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

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,901
    Quote Originally Posted by kermit View Post
    I am not sure this buys you much, given how easy it is to sidestep a const qualification.
    Not unless you're using evil casts. Otherwise the compiler will barf and you don't get a runtime error and everyone is happy.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,528
    Quote Originally Posted by Elysia View Post
    Not unless you're using evil casts. Otherwise the compiler will barf and you don't get a runtime error and everyone is happy.
    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.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,901
    That's true. C has too many ways to circumvent const. At least they'll be more protected against stupid bugs, though.
    In the future, we'll simply adopt: "Use const, and reduce your runtime bugs by 10%!"
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    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.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,901
    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?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,751
    Quote Originally Posted by Elysia View Post
    That's true. C has too many ways to circumvent const.
    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).

  15. #15
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by Elysia View Post
    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?
    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.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointer to a function pointer
    By @nthony in forum C Programming
    Replies: 3
    Last Post: 05-30-2010, 06:13 PM
  2. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 11:10 AM
  3. Quick Pointer Question
    By gwarf420 in forum C Programming
    Replies: 15
    Last Post: 06-01-2008, 04:47 PM
  4. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 04:36 AM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 01:04 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21