segfault when strcmp

Discussion in 'C Programming' started by Robert Mens, Oct 22, 2003.

  1. Robert Mens

    Robert Mens Guest

    Hi,

    I've got this problem with this project i am working on, i am
    a bit new to c so i don't know why this happens.

    string is read from a telnet socket.

    Here's the piece of code that segfaults:

    struct login_usertable{
    char username;
    char password;
    int status; /* 0=disconnected, 1=need password, 2=connected */
    };

    struct login_usertable user;

    int login_fillusers(){
    user.username="robert";
    user.password="test";
    user.status=0;
    }

    int login_requesthandler(int socket,char *string){
    if(user.status==0) login_showlogin(socket, 0);
    if(user.status==1){
    if(strcmp((char *)user.username,string)==0){ //segfaults
    printf("logged in\n");
    login_showlogin(socket, 1);
    }else{
    printf("err\n");
    login_showlogin(socket, 0);
    }
    }
    }

    What's wrong with it?

    Thanks in Advance,

    Robert

    --
    ln[dot]tenlap[at]snem_trebor
    read reversed and fill dot&at for email
    Robert Mens, Oct 22, 2003
    #1
    1. Advertising

  2. Robert Mens <> scribbled the following:
    > Hi,


    > I've got this problem with this project i am working on, i am
    > a bit new to c so i don't know why this happens.


    > string is read from a telnet socket.


    > Here's the piece of code that segfaults:


    > struct login_usertable{
    > char username;


    Take a close look at the declaration of this field. Note the type.

    > char password;
    > int status; /* 0=disconnected, 1=need password, 2=connected */
    > };


    > struct login_usertable user;


    > int login_fillusers(){
    > user.username="robert";


    You are shoving a char * into a char. Undefined behaviour.

    > user.password="test";
    > user.status=0;
    > }


    > int login_requesthandler(int socket,char *string){
    > if(user.status==0) login_showlogin(socket, 0);
    > if(user.status==1){
    > if(strcmp((char *)user.username,string)==0){ //segfaults


    The undefined behaviour in the first line of login_fillusers()
    already destroyed all hope of user.username being a valid char *
    value. No amount of casting will magically change it back. Thus
    this strcmp() call is pointless.

    > printf("logged in\n");
    > login_showlogin(socket, 1);
    > }else{
    > printf("err\n");
    > login_showlogin(socket, 0);
    > }
    > }
    > }


    > What's wrong with it?


    Try changing the char fields in struct login_usertable to char * and
    see if it works.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "Immanuel Kant but Genghis Khan."
    - The Official Graffitist's Handbook
    Joona I Palaste, Oct 22, 2003
    #2
    1. Advertising

  3. Robert Mens

    Mark Gordon Guest

    On Wed, 22 Oct 2003 22:04:27 +0200
    Robert Mens <> wrote:

    > Hi,
    >
    > I've got this problem with this project i am working on, i am
    > a bit new to c so i don't know why this happens.
    >
    > string is read from a telnet socket.
    >
    > Here's the piece of code that segfaults:


    #include <string.h> /* for string functions */
    #include <stdio.h> /* for printf and friends */

    > struct login_usertable{
    > char username;
    > char password;


    char *username;
    char *password;

    /*
    This was your big problem. You want pointer to strings if you are going
    to make them point to something, which you do below. A single char as
    you declared them can only store a single character.

    Alternatively you might want character arrays, depending on what the
    rest of your program is. However, you would then have to change your
    login_fillusers function.
    */

    > int status; /* 0=disconnected, 1=need password, 2=connected */
    > };
    >
    > struct login_usertable user;
    >
    > int login_fillusers(){

    void login_fillusers(){

    /* You don't return a value, so tell the compiler the truth */

    > user.username="robert";
    > user.password="test";
    > user.status=0;
    > }
    >
    > int login_requesthandler(int socket,char *string){

    void login_requesthandler(int socket,char *string){

    /* Again, you don't return an int so don't tell the compiler you will */

    > if(user.status==0) login_showlogin(socket, 0);
    > if(user.status==1){
    > if(strcmp((char *)user.username,string)==0){


    if(strcmp(user.username,string)==0){
    /*
    I bet you added the cast above to shut up the compiler. That was wrong,
    the compiler was warning because YOU had got it wrong.
    */

    > //segfaults

    /*
    The // style comment was introduced in C99 and may not be supported by
    your compiler when invoked in conforming mode (something you should do)
    so it is better to use the old style comments like I have been doing.

    Old style comments also survive reformatting on posting to Usenet
    whereas // style comments often get broken.
    */

    > printf("logged in\n");
    > login_showlogin(socket, 1);
    > }else{
    > printf("err\n");
    > login_showlogin(socket, 0);
    > }
    > }
    > }
    >
    > What's wrong with it?


    See above.

    For the future you should find out how to invoke your compiler in ISO
    compliant mode with a a high level of warnings. I got masses of warnings
    when I did this. Also don't ignore warnings or silence them with casts
    since at your level I don't think you know enough to understand which
    warnings you can ignore.
    --
    Mark Gordon
    Paid to be a Geek & a Senior Software Developer
    Although my email address says spamtrap, it is real and I read it.
    Mark Gordon, Oct 22, 2003
    #3
  4. In article <bn6nr9$mdb$>, Robert Mens wrote:
    > Hi,
    >
    > I've got this problem with this project i am working on, i am
    > a bit new to c so i don't know why this happens.
    >
    > string is read from a telnet socket.
    >
    > Here's the piece of code that segfaults:
    >
    > struct login_usertable{
    > char username;
    > char password;
    > int status; /* 0=disconnected, 1=need password, 2=connected */
    > };
    >
    > struct login_usertable user;
    >
    > int login_fillusers(){
    > user.username="robert";
    > user.password="test";



    Both user.username and user.password are characters, not
    strings. Therefore you can't make those two assignments.

    Try this instead:

    #define MAXLENGTH 64

    struct login_usertable {
    char username[MAXLENGTH];
    char password[MAXLENGTH];
    int status;
    }

    int login_fillusers()
    {
    strncpy(user.username, "robert", MAXLENGTH);
    strncpy(user.password, "piggsvin", MAXLENGTH);
    /* etc. */


    Read up on strings in some book.


    --
    Andreas Kähäri
    Andreas Kahari, Oct 22, 2003
    #4
  5. Robert Mens

    Robert Mens Guest

    Robert Mens wrote:

    > Hi,
    >
    > I've got this problem with this project i am working on, i am
    > a bit new to c so i don't know why this happens.
    >
    > string is read from a telnet socket.
    >
    > Here's the piece of code that segfaults:
    >
    > struct login_usertable{
    > char username;
    > char password;
    > int status; /* 0=disconnected, 1=need password, 2=connected */
    > };
    >
    > struct login_usertable user;
    >
    > int login_fillusers(){
    > user.username="robert";
    > user.password="test";
    > user.status=0;
    > }
    >
    > int login_requesthandler(int socket,char *string){
    > if(user.status==0) login_showlogin(socket, 0);
    > if(user.status==1){
    > if(strcmp((char *)user.username,string)==0){ //segfaults
    > printf("logged in\n");
    > login_showlogin(socket, 1);
    > }else{
    > printf("err\n");
    > login_showlogin(socket, 0);
    > }
    > }
    > }
    >
    > What's wrong with it?
    >
    > Thanks in Advance,
    >
    > Robert
    >


    Thanks a lot for your answers
    solved it now by places the char * thingys
    --
    ln[dot]tenalp[at]snem_trebor
    read reversed and fill dot&at for email
    Robert Mens, Oct 22, 2003
    #5
  6. On Wed, 22 Oct 2003 20:39:45 +0000 (UTC), Andreas Kahari
    <> wrote:

    > strncpy(user.username, "robert", MAXLENGTH);
    > strncpy(user.password, "piggsvin", MAXLENGTH);
    > /* etc. */


    I wouldn't recommend strncpy here - it doesn't terminate the string if it's
    too long to fit. Use strncat instead, after initialising the first element
    of the destination to zero.

    -- Mat.
    Mathew Hendry, Oct 22, 2003
    #6
  7. Mathew Hendry <> wrote in message news:<>...
    > On Wed, 22 Oct 2003 20:39:45 +0000 (UTC), Andreas Kahari
    > <> wrote:
    >
    > > strncpy(user.username, "robert", MAXLENGTH);
    > > strncpy(user.password, "piggsvin", MAXLENGTH);
    > > /* etc. */

    >
    > I wouldn't recommend strncpy here - it doesn't terminate the string if it's
    > too long to fit.


    It rather depends on the intended usage. Maximum memory utilisation of
    fixed width fields is exactly what strncpy was designed for.

    Of course, subsequent use of the field as an assumed string (e.g. with
    strcmp) is not likely to have a good outcome.

    However, fprintf specifically supports such fields too...

    printf("%.*s\n", MAXLENGTH, user.username);

    ....as the argument to %s need only be an array, it needn't be a
    string.

    --
    Peter
    Peter Nilsson, Oct 23, 2003
    #7
    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. Shane Peck

    strcmp problem

    Shane Peck, Sep 19, 2003, in forum: C++
    Replies:
    6
    Views:
    2,356
    Kevin Goodsell
    Sep 22, 2003
  2. muser

    strcmp

    muser, Oct 3, 2003, in forum: C++
    Replies:
    6
    Views:
    1,114
    Frank Schmitt
    Oct 9, 2003
  3. Andrej Hocevar

    please help with strcmp()

    Andrej Hocevar, Jul 19, 2003, in forum: C Programming
    Replies:
    3
    Views:
    326
    Gordon Burditt
    Jul 19, 2003
  4. Allan Bruce

    strcmp but with '\n' as the terrminator

    Allan Bruce, Jul 19, 2003, in forum: C Programming
    Replies:
    53
    Views:
    1,387
    Arthur J. O'Dwyer
    Jul 30, 2003
  5. Andrey Vul
    Replies:
    8
    Views:
    685
    Richard Bos
    Jul 30, 2010
Loading...

Share This Page