Can't dereference pointer to stack?

Discussion in 'C++' started by TuAmigoFiel@gmail.com, Feb 10, 2006.

  1. Guest

    Why does the following give a segmentation fault?

    void breakme(char* st) {
    char* cp = st;
    *cp = 'x' // This is the problem line.
    }

    int main() {
    char* mine = "teststringfortestingpurposes";
    breakme(mine);
    }
     
    , Feb 10, 2006
    #1
    1. Advertising

  2. * :
    > Why does the following give a segmentation fault?
    >
    > void breakme(char* st) {
    > char* cp = st;
    > *cp = 'x' // This is the problem line.
    > }
    >
    > int main() {
    > char* mine = "teststringfortestingpurposes";
    > breakme(mine);
    > }


    Why not?

    The program has undefined behavior.

    Therefore, anything can happen, including a SIGSEGV.

    If instead you ask, why does C++ allow that particular nastie?

    That's to maintain backwards compatibility with C.


    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Feb 10, 2006
    #2
    1. Advertising

  3. Guest

    wrote:
    > Why does the following give a segmentation fault?
    >
    > void breakme(char* st) {
    > char* cp = st;
    > *cp = 'x' // This is the problem line.
    > }
    >
    > int main() {
    > char* mine = "teststringfortestingpurposes";


    This string is constant and cannot be changed. Change to "char mine[]
    = " and it will work. This is because you will be declairing an array
    of char instead of a pointer to an unmutable string.
     
    , Feb 10, 2006
    #3
  4. dakka Guest

    wrote:
    > Why does the following give a segmentation fault?
    >
    > void breakme(char* st) {
    > char* cp = st;
    > *cp = 'x' // This is the problem line.
    > }
    >
    > int main() {
    > char* mine = "teststringfortestingpurposes";
    > breakme(mine);
    > }
    >

    Modifying a static string literal is - whilst legal - undefined. The
    statement
    char* mine = "teststringfortestingpurposes";
    is actually converting a const char * to char * (again which is legal
    but deprecated). Result - undefined. In your case (probably most
    compilers will do the same) - dummy spit.

    --dakka
     
    dakka, Feb 10, 2006
    #4
  5. Guest

    Thanks everyone.

    This was from a string manipulation function I wrote that was seemingly
    not working. The worst part is that it would have worked if I hadn't
    used a string literal to test it.
     
    , Feb 10, 2006
    #5
  6. Guest

    hmm..
    now I'm getting worried. Has something happened with c++, that
    I am not aware of?
    you can even do:(if you like to i dont see why though)
    void breakme(char* st) {
    char* cp = st;
    *cp = 'x'; }


    int main() {
    breakme("teststringfortestingpurposes");
    }
    This is a basic pointer..
    I am a bit confused now.
    And just so you know, I tested this (borland compiler set to ansi
    complience and force c++ compile).
    Please help me understand.
    /Jesper
     
    , Feb 10, 2006
    #6
  7. Default User Guest

    wrote:

    > hmm..
    > now I'm getting worried. Has something happened with c++, that
    > I am not aware of?
    > you can even do:(if you like to i dont see why though)
    > void breakme(char* st) {
    > char* cp = st;
    > *cp = 'x'; }
    >
    >
    > int main() {
    > breakme("teststringfortestingpurposes");
    > }
    > This is a basic pointer..
    > I am a bit confused now.
    > And just so you know, I tested this (borland compiler set to ansi
    > complience and force c++ compile).
    > Please help me understand.


    Understand what? You don't mention what it is that confuses you.

    The code fragments shown exhibit undefined behavior. It may seem like a
    tautology, but there is no defined behavior for undefined behavior. The
    code is broken and should not be used, but you can't expect anything in
    particular from it.



    Brian
     
    Default User, Feb 10, 2006
    #7
  8. Kaz Kylheku Guest

    Alf P. Steinbach wrote:
    > * :
    > > Why does the following give a segmentation fault?
    > >
    > > void breakme(char* st) {
    > > char* cp = st;
    > > *cp = 'x' // This is the problem line.
    > > }
    > >
    > > int main() {
    > > char* mine = "teststringfortestingpurposes";
    > > breakme(mine);
    > > }

    >
    > Why not?
    >
    > The program has undefined behavior.
    >
    > Therefore, anything can happen, including a SIGSEGV.
    >
    > If instead you ask, why does C++ allow that particular nastie?
    >
    > That's to maintain backwards compatibility with C.


    The idea that modification of literals is undefined in C++ for the sake
    of compatibility with C is quite ridiculous.

    Other languages have similar restrictions against what is essentially
    self-modifying code.

    Modification of literals is also undefined in Lisp for instance. Is
    that for compatibility with C also?

    (setf (car '(a b c)) 42) ;; Nasal demons!
    (setf (char "abc" 1) #\z) ;; ditto

    This type of liberty with respect to literals allows for ROM-able code:
    both the program code and its literal data can be compiled into a
    single program image, which can then be put into write-protected
    memory. The program can reference that data using a direct pointer into
    that memory.

    A literal should be thought of as a component of the program itself,
    and not some external data. Through a literal quoting mechanism, a
    program gains access to a piece of itself which it can use as data in a
    computation.

    If such objects had to be modifiable, then only their initial values
    could be stored in that read-only memory. Modifiable storage would have
    to be allocated for them at program startup, and the initial values
    copied there. This is a waste of time and storage for objects which are
    treated as immutable.

    And let's not forget that immutable objects can also be compressed
    together to save space through substructure sharing. If one string
    literal matches a suffix of another, or possible the entire string,
    then it can be represented as a pointer to that suffix. If those
    objects could be modified, there would be surprising behaviors.
    Changing one literal would change some unrelated string that shares
    storage with it.

    Many C and C++ implementations for virtual memory systems provide a
    nice, accurate diagnostic for this error. The compiler places string
    literals into the same object file sections as code, so literals are
    co-allocated with code. The dynamic loader maps the program's
    executable image file into the process address space as read only, so
    any self modification (code or literal data) results in an instant
    violation. It's a nice setup.
     
    Kaz Kylheku, Feb 10, 2006
    #8
  9. * Kaz Kylheku:
    > Alf P. Steinbach wrote:
    >> * :
    >>> Why does the following give a segmentation fault?
    >>>
    >>> void breakme(char* st) {
    >>> char* cp = st;
    >>> *cp = 'x' // This is the problem line.
    >>> }
    >>>
    >>> int main() {
    >>> char* mine = "teststringfortestingpurposes";
    >>> breakme(mine);
    >>> }

    >> Why not?
    >>
    >> The program has undefined behavior.
    >>
    >> Therefore, anything can happen, including a SIGSEGV.
    >>
    >> If instead you ask, why does C++ allow that particular nastie?
    >>
    >> That's to maintain backwards compatibility with C.

    >
    > The idea that modification of literals is undefined in C++ for the sake
    > of compatibility with C is quite ridiculous.


    Yes.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Feb 10, 2006
    #9
  10. Bo Persson Guest

    <> skrev i meddelandet
    news:...
    > hmm..
    > now I'm getting worried. Has something happened with c++, that
    > I am not aware of?
    > you can even do:(if you like to i dont see why though)
    > void breakme(char* st) {
    > char* cp = st;
    > *cp = 'x'; }
    >
    >
    > int main() {
    > breakme("teststringfortestingpurposes");
    > }
    > This is a basic pointer..


    Yes, but the type of the string literal is 'const char*'. It is
    convertible to non-const char*, just to be compatible with old C code.

    Actually modifying (*cp = 'x';) the const data is what is the
    undefined behaviour.

    On some other compilers, this would cause a segfault, as the string
    literal could be stored in a read-only segment. As usual though, one
    possible outcome of the undefined behaviour is the nasty 'seems to
    work'.

    > I am a bit confused now.


    We all are. .-)


    Bo Persson
     
    Bo Persson, Feb 11, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Denis Palmeiro

    NULL Pointer Dereference

    Denis Palmeiro, Jul 8, 2003, in forum: C Programming
    Replies:
    10
    Views:
    684
    Shill
    Jul 16, 2003
  2. somenath

    pointer dereference

    somenath, Jul 12, 2007, in forum: C Programming
    Replies:
    34
    Views:
    946
    Anurag
    Jul 18, 2007
  3. somenath

    pointer dereference

    somenath, Aug 9, 2007, in forum: C Programming
    Replies:
    12
    Views:
    691
    Martin Ambuhl
    Aug 10, 2007
  4. Nyang A. Phra

    Function pointer dereference security

    Nyang A. Phra, Nov 11, 2007, in forum: C Programming
    Replies:
    0
    Views:
    306
    Nyang A. Phra
    Nov 11, 2007
  5. Nyang A. Phra

    Function pointer dereference security

    Nyang A. Phra, Nov 11, 2007, in forum: C Programming
    Replies:
    13
    Views:
    786
    Kevin D. Quitt
    Dec 20, 2007
Loading...

Share This Page