strange problem

Discussion in 'C++' started by junw2000@gmail.com, May 28, 2006.

  1. Guest

    The following code can be compiled. But When I run it, it causes
    "Segmentation fault".

    #include <iostream>

    int main(){
    char **c1;

    *c1 = "HOW"; // LINE1

    std::cout <<"1"<<std::endl;

    ++(*c1);
    *c1 = "ARE";

    std::cout <<"2"<<std::endl;
    ++(*c1);
    *c1 = "YOU";
    std::cout <<"3"<<std::endl;
    std::cout <<*c1<<std::endl;
    (*c1)++;
    std::cout <<*c1<<std::endl;
    (*c1)++;
    std::cout <<*c1<<std::endl;

    }

    Why LINE1 causes "Segmentation fault"?

    What is the correct way to write the above code?

    Thanks a lot.
    , May 28, 2006
    #1
    1. Advertising

  2. * :
    > The following code can be compiled. But When I run it, it causes
    > "Segmentation fault".
    >
    > #include <iostream>
    >
    > int main(){
    > char **c1;
    >
    > *c1 = "HOW"; // LINE1
    >
    > std::cout <<"1"<<std::endl;
    >
    > ++(*c1);
    > *c1 = "ARE";
    >
    > std::cout <<"2"<<std::endl;
    > ++(*c1);
    > *c1 = "YOU";
    > std::cout <<"3"<<std::endl;
    > std::cout <<*c1<<std::endl;
    > (*c1)++;
    > std::cout <<*c1<<std::endl;
    > (*c1)++;
    > std::cout <<*c1<<std::endl;
    >
    > }
    >
    > Why LINE1 causes "Segmentation fault"?


    Dereferencing an uninitialized pointer - Undefined Behavior.


    > What is the correct way to write the above code?


    Rather, what's a better way to use your compiler? Up the warning
    levels. Ensure that you get a clean compile (no warnings), always.

    To output the text "HOW ARE YOU", do

    std::cout << "HOW ARE YOU" << std::endl;

    Just avoid pointers, they're dangerous.

    --
    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, May 28, 2006
    #2
    1. Advertising

  3. Luke Meyers Guest

    wrote:
    > The following code can be compiled. But When I run it, it causes
    > "Segmentation fault".


    Yes. The english name for that is "invalid memory access."

    > #include <iostream>
    >
    > int main(){
    > char **c1;


    This is a variable which holds a memory address. If it held a valid
    address (it doesn't, unless by chance), the contents of the memory at
    said address would be another memory address. If *that* address were
    valid, it would be the location of a variable of type char.

    A little confusing? Yes. Easy to mix up and make a mistake, resulting
    in a seg fault? Yup.

    > *c1 = "HOW"; // LINE1


    Right, so here you're dereferencing a pointer which does not hold a
    valid memory address. Hence, seg fault. If *c1 held a valid pointer
    (to a variable of type char*), the result of this operation would be to
    make *c1 point to the area in static memory containing the string
    literal "HOW."

    > What is the correct way to write the above code?


    Use std::string. It exists to prevent you from feeling the pain you
    now feel.

    Luke
    Luke Meyers, May 28, 2006
    #3
  4. Guest

    Thanks.
    Certainly, std::string is safer. I am trying to learn
    pointer-to-pointer to char.
    If using C language, how to initialize c1 to three strings---"HOW",
    "ARE", "YOU"?

    Thanks again.
    , May 28, 2006
    #4
  5. Phlip Guest

    junw2000 wrote:

    > Certainly, std::string is safer.


    This newsgroup always instructs students to start with the Standard library
    stuff.

    > I am trying to learn
    > pointer-to-pointer to char.
    > If using C language, how to initialize c1 to three strings---"HOW",
    > "ARE", "YOU"?


    Start with three pointers to characters:

    char const * strings[] = { "HOW", "ARE", "YOU" };

    And point to the first one:

    char const * * p = strings;

    Now p[1] points to "ARE", and p[1][1] points to 'R'.

    You might be able to Google for "aggregate initializers" from here.

    --
    Phlip
    http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
    Phlip, May 28, 2006
    #5
  6. Luke Meyers Guest

    wrote:
    > Certainly, std::string is safer. I am trying to learn
    > pointer-to-pointer to char.


    Sure. The best way, in my opinion, to learn to use char** correctly is
    to first learn about using, for example, int**. Integers are easier to
    deal with because you don't have the added complications of string
    literals, string lengths, null termination, etc. It may sound like I'm
    being perversely intransigent, but the fact is that the fundamental
    things you're failing to understand, in the code you posted, are issues
    which pertain to all pointer-to-pointer types. The reason you're
    failing to understand them has a lot to do with the fact that you're
    trying to jump straight into the complexities of char** without
    understanding those fundamentals.

    > If using C language, how to initialize c1 to three strings---"HOW",
    > "ARE", "YOU"?


    This isn't a C newsgroup. If you want help with C, try comp.lang.c
    (actually, I see that you already did so).

    Luke
    Luke Meyers, May 28, 2006
    #6
  7. Phlip Guest

    Luke Meyers wrote:

    >> If using C language, how to initialize c1 to three strings---"HOW",
    >> "ARE", "YOU"?

    >
    > This isn't a C newsgroup. If you want help with C, try comp.lang.c
    > (actually, I see that you already did so).


    Mr. Manners reminds the Gentle Poster that some neophytes have not yet
    learned to write, "if using C-style C++..."

    Note the transition was from std::string; the poster was trying to
    distinguish from the C++ Standard Library.

    --
    Phlip
    http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
    Phlip, May 28, 2006
    #7
  8. LuB Guest

    wrote:
    > The following code can be compiled. But When I run it, it causes
    > "Segmentation fault".
    >
    > #include <iostream>
    >
    > int main(){


    char* d1 = "";
    char** c1 = &d1;

    >
    > *c1 = "HOW"; // LINE1
    >
    > std::cout <<"1"<<std::endl;
    >
    > ++(*c1);
    > *c1 = "ARE";
    >
    > std::cout <<"2"<<std::endl;
    > ++(*c1);
    > *c1 = "YOU";
    > std::cout <<"3"<<std::endl;
    > std::cout <<*c1<<std::endl;
    > (*c1)++;
    > std::cout <<*c1<<std::endl;
    > (*c1)++;
    > std::cout <<*c1<<std::endl;
    >
    > }



    As the previous posters implied, this approach is not recommended.

    -LuB
    LuB, May 28, 2006
    #8
  9. LuB schrieb:
    >>#include <iostream>
    >>
    >>int main(){

    >
    >
    > char* d1 = "";
    > char** c1 = &d1;


    Are you sure you want to do this?

    >
    >> *c1 = "HOW"; // LINE1
    >>
    >> std::cout <<"1"<<std::endl;
    >>
    >> ++(*c1);


    Advances the pointer after d1.

    >> *c1 = "ARE";


    Will do bad things.

    >> std::cout <<"2"<<std::endl;
    >> ++(*c1);
    >> *c1 = "YOU";


    Even worser.

    >> std::cout <<"3"<<std::endl;
    >> std::cout <<*c1<<std::endl;
    >> (*c1)++;
    >> std::cout <<*c1<<std::endl;
    >> (*c1)++;
    >> std::cout <<*c1<<std::endl;
    >>
    >>}

    >
    >
    >
    > As the previous posters implied, this approach is not recommended.


    And does not work. You should better use std::string and std::vector.

    Thomas
    Thomas J. Gritzan, May 28, 2006
    #9
  10. Jim Langston Guest

    <> wrote in message
    news:...
    > The following code can be compiled. But When I run it, it causes
    > "Segmentation fault".
    >
    > #include <iostream>
    >
    > int main(){
    > char **c1;


    Okay, c1 is a pointer to a pointer of char.

    > *c1 = "HOW"; // LINE1


    Here you are saying to change the contents of where c1 points to point to
    the string literal "HOW". But, c1 is not yet pointing to valid memory.
    It's pointing anywhere since it was never initialized. So you are
    attempting to change memory that your program doesn't "own", hence the
    segmentation fault.

    What it looks like you are trying here is to have c1 to be an array of
    pointers to char. So you need to set aside the memory for the pointers.

    This would work:

    char* c1[3];
    c1[0] = "HOW";

    because now c1 is an array of 3 pointers to char, and the memory has been
    allocated for 3 pointers. Also, though, you could now reference these by
    your char** such as;

    char* c0[3];
    char** c1 = c0;
    *c0 = "HOW";

    because c1 now points to memory that has been allocated (by the declaration
    of c0 which allocated the space for 3 pointers).
    Jim Langston, May 28, 2006
    #10
  11. wrote:
    > The following code can be compiled. But When I run it, it causes
    > "Segmentation fault".
    >
    > #include <iostream>
    >
    > int main(){
    > char **c1;


    const char * c1;

    > *c1 = "HOW"; // LINE1


    c1 = "HOW";

    [snip]

    the rest you can figure out ;-)
    Diego Martins, May 29, 2006
    #11
  12. LuB Guest

    Thomas J. Gritzan wrote:
    > LuB schrieb:
    > >>#include <iostream>
    > >>
    > >>int main(){

    > >
    > >
    > > char* d1 = "";
    > > char** c1 = &d1;

    >
    > Are you sure you want to do this?


    No I'm not sure. What do you think?

    >
    > >
    > >> *c1 = "HOW"; // LINE1
    > >>
    > >> std::cout <<"1"<<std::endl;
    > >>
    > >> ++(*c1);

    >
    > Advances the pointer after d1


    I'm sure you are correct - but I can't tell .. but I've no idea what
    your point is. *c1 is now "OW"

    >
    > >> *c1 = "ARE";

    >
    > Will do bad things.


    Again - I'm sure you are correct ... but what are you talking about?

    g++ isn't complaining.

    >
    > >> std::cout <<"2"<<std::endl;
    > >> ++(*c1);
    > >> *c1 = "YOU";

    >
    > Even worser.


    Again - I can't disagree ... cause I've no idea what you are talking
    about.

    Someone else posted this ... I added two lines at the top ... the
    program compiles and appears to run in g++. I'm having trouble parsing
    your post. Again, I'm sure your are correct - but I've no idea what you
    are saying?

    >
    > >> std::cout <<"3"<<std::endl;
    > >> std::cout <<*c1<<std::endl;
    > >> (*c1)++;
    > >> std::cout <<*c1<<std::endl;
    > >> (*c1)++;
    > >> std::cout <<*c1<<std::endl;
    > >>
    > >>}

    > >
    > >
    > >
    > > As the previous posters implied, this approach is not recommended.

    >
    > And does not work. You should better use std::string and std::vector.


    Ok ... I'm not saying your wrong.

    But I beg to take issue with your verbage.

    It does indeed work.

    $ g++ -v
    Using built-in specs.
    Target: i386-redhat-linux
    Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
    --infodir=/usr/share/info --enable-shared --enable-threads=posix
    --enable-checking=release --with-system-zlib --enable-__cxa_atexit
    --disable-libunwind-exceptions --enable-libgcj-multifile
    --enable-languages=c,c++,objc,java,f95,ada --enable-java-awt=gtk
    --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
    --host=i386-redhat-linux
    Thread model: posix
    gcc version 4.0.2 20051125 (Red Hat 4.0.2-8)

    $ g++ -o test.exe test3.cpp
    $ ./test.exe
    1
    2
    3
    YOU
    OU
    U
    [zentdd@s5 cpp]$


    Maybe you have some mystical notion about _your_ understanding or
    definition of the word WORK.

    If so - maybe thats all I'd need to clarify what you're talking about.

    I don't know if its portable. I don't know if it works all the time
    everywhwere. I don't know if its to spec. I don't know if its
    dangerous. I don't claim any of those things. And I think it would
    likely be impossible to prove many such things via formal proof.

    So again - I'm sure that given your definition of the word "Work" - you
    are correct. But given the context of your statement - I'm at a loss
    for what you are talking about.

    Imagine a student compiling this program, running it - turning it in --
    and the teacher claiming "it doesn't work - use .... instead." and
    givng the student an F.

    And how about ... "are you sure you want to do this?" "advances the
    pointer" "will do bad things" "even worser".

    Does that teach the student anything?

    Your post was just noise. The only people that know what you're talking
    about ... already knew what you were talking about -- if indeed, you
    said anything worth talking about.
    LuB, Jun 10, 2006
    #12
    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. Kload

    Strange Timing Problem

    Kload, Oct 23, 2003, in forum: VHDL
    Replies:
    2
    Views:
    587
    Kload
    Oct 23, 2003
  2. Akshaye
    Replies:
    1
    Views:
    736
    Hemant Gupta
    Feb 9, 2004
  3. Pedro Miguel Carvalho
    Replies:
    2
    Views:
    1,125
    Pedro Miguel Carvalho
    Oct 25, 2004
  4. Harvey Twyman
    Replies:
    8
    Views:
    562
    August Derleth
    Oct 25, 2003
  5. championsleeper
    Replies:
    0
    Views:
    573
    championsleeper
    Jan 26, 2005
Loading...

Share This Page