segfault when strcmp

R

Robert Mens

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
 
J

Joona I Palaste

Robert Mens said:
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.
 
M

Mark Gordon

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 said:
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.
 
A

Andreas Kahari

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.
 
R

Robert Mens

Robert said:
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
 
M

Mathew Hendry

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.
 
P

Peter Nilsson

Mathew Hendry said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top