segmentation fault (core dumped)

P

Pieter Droogendijk

Just having a bit of trouble programming with C under FreeBSD 5.1 using the
gcc compiler. I'm a bit new to C so my apologies if the answer to my
question appear obvious :)

Basically I've written a function that will check whether a string is an ip
address (see the function isIP below). During my attempt at debugging this
problem I inserted a printf statement before the return command from the
statement, and also a printf statement after the function's call.
Strangely, the last printf in the function prints, but not the printf after
the function has been called. So somewhere something causes a problem
during the attempt at exiting the function.

FreeBSD prints:
Segmentation fault (core dumped)
which from what I've read basically means that I'm mayhaps addressing memory
outside the current segment. I've got no idea what's wrong, but also more
importantly, I don't know how to go about debugging the problem? So any
insights into debugging segmentation faults (or core dumps) would be
appreciated. I tried using lint but that doesn't really give me any useful
information...or not any information useful to me ;)

Thanks for your time, much appreciated :)

/*
* checks whether a string is an IP address
* (it basically splits the string, checks that it has 4 segments and that
each segment is a number between 0 and 255)
*/


#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int isNumber(char* chars);

int isIP(const char *ip) {

char* segment;
int segmentcount = 0;
char iptemp[3+1+3+1+3+1+3+1]; /* Ip address won't get longer than this */
// we mustn't change the IP pointer (strtok changes content)
memcpy(iptemp, ip, strlen(ip)+1 );

segment = strtok(iptemp, ".");
while (segment != NULL) {
// increment our number of segments
segmentcount++;

// check whether the retrieved segment is a digit
if (!isNumber( segment )) {
return 0;
}

// check whether the number is between 0 and 255
if ( atoi(segment) > 255 ) {
return 0;
}

// retrieve the next segment
segment = strtok(NULL, ".");
}

// an IP address consists of 4 segments
if (segmentcount != 4) {
return 0;
}

return 1;
}



The function isNumber is just:

int isNumber(char* chars) {

char* ptr;
int asciicode;
ptr = chars;
while (*ptr != '\0') {
/* You knew about isascii(), but not about isdigit()? */
if (!isdigit (*ptr))
return 0;
 
N

N.S. du Toit

Just having a bit of trouble programming with C under FreeBSD 5.1 using the
gcc compiler. I'm a bit new to C so my apologies if the answer to my
question appear obvious :)

Basically I've written a function that will check whether a string is an ip
address (see the function isIP below). During my attempt at debugging this
problem I inserted a printf statement before the return command from the
statement, and also a printf statement after the function's call.
Strangely, the last printf in the function prints, but not the printf after
the function has been called. So somewhere something causes a problem
during the attempt at exiting the function.

FreeBSD prints:
Segmentation fault (core dumped)
which from what I've read basically means that I'm mayhaps addressing memory
outside the current segment. I've got no idea what's wrong, but also more
importantly, I don't know how to go about debugging the problem? So any
insights into debugging segmentation faults (or core dumps) would be
appreciated. I tried using lint but that doesn't really give me any useful
information...or not any information useful to me ;)

Thanks for your time, much appreciated :)

/*
* checks whether a string is an IP address
* (it basically splits the string, checks that it has 4 segments and that
each segment is a number between 0 and 255)
*/
int isIP(const char *ip) {

char* segment;
int segmentcount = 0;

//--------------------------------------------------------------------------
---
// we mustn't change the IP pointer (strtok changes content)
char *iptemp;
memcpy(iptemp, ip, strlen(ip)+1 );
//--------------------------------------------------------------------------
---

segment = strtok(iptemp, ".");
while (segment != NULL) {
// increment our number of segments
segmentcount++;

// check whether the retrieved segment is a digit
if (!isNumber( segment )) {
return 0;
}

// check whether the number is between 0 and 255
if ( atoi(segment) > 255 ) {
return 0;
}

// retrieve the next segment
segment = strtok(NULL, ".");
}

// an IP address consists of 4 segments
if (segmentcount != 4) {
return 0;
}

return 1;
}



The function isNumber is just:

int isNumber(char* chars) {

char* ptr;
int asciicode;

ptr = &chars[0];
while (*ptr != '\0') {
// check to see whether the character is ascii
if (!isascii(*ptr)) {
return 0;
}

asciicode = (int) *ptr;
// check that the ASCII code is within 48 -> 57
if ( (asciicode < 48) || (asciicode > 57) ) {
return 0;
}

ptr++;
}

return 1;
}
 
R

Richard Heathfield

N.S. du Toit said:
Just having a bit of trouble programming with C under FreeBSD 5.1 using
the
gcc compiler. I'm a bit new to C so my apologies if the answer to my
question appear obvious :)

Basically I've written a function that will check whether a string is an
ip
address (see the function isIP below). During my attempt at debugging
this problem I inserted a printf statement before the return command from
the statement, and also a printf statement after the function's call.
Strangely, the last printf in the function prints, but not the printf
after
the function has been called. So somewhere something causes a problem
during the attempt at exiting the function.

FreeBSD prints:
Segmentation fault (core dumped)
which from what I've read basically means that I'm mayhaps addressing
memory
outside the current segment. I've got no idea what's wrong, but also more
importantly, I don't know how to go about debugging the problem? So any
insights into debugging segmentation faults (or core dumps) would be
appreciated. I tried using lint but that doesn't really give me any
useful information...or not any information useful to me ;)

Thanks for your time, much appreciated :)

/*
* checks whether a string is an IP address
* (it basically splits the string, checks that it has 4 segments and that
each segment is a number between 0 and 255)
*/
int isIP(const char *ip) {

char* segment;
int segmentcount = 0;

//--------------------------------------------------------------------------

There's a problem right here. You haven't allocated any storage for iptemp.

char *iptemp = malloc(strlen(ip) + 1);
if(iptemp != NULL)
{
strcpy(iptemp, ip);

Now you can work on iptemp. When you've finished with it, free(iptemp) to
prevent a memory leak.
 
M

Martin Ambuhl

N.S. du Toit said:
Just having a bit of trouble programming with C under FreeBSD 5.1 using the
gcc compiler. I'm a bit new to C so my apologies if the answer to my
question appear obvious :)

Basically I've written a function that will check whether a string is an ip
address (see the function isIP below). During my attempt at debugging this
problem I inserted a printf statement before the return command from the
statement, and also a printf statement after the function's call.
Strangely, the last printf in the function prints, but not the printf after
the function has been called. So somewhere something causes a problem
during the attempt at exiting the function.

FreeBSD prints:
Segmentation fault (core dumped)
which from what I've read basically means that I'm mayhaps addressing memory
outside the current segment.

No shit, Sherlock.
[snip]
char *iptemp;
memcpy(iptemp, ip, strlen(ip)+1 );

What space do you think the uninitialized pointer iptemp points to?
 
N

N.S. du Toit

char *iptemp = malloc(strlen(ip) + 1);
if(iptemp != NULL)
{
strcpy(iptemp, ip);

Now you can work on iptemp. When you've finished with it, free(iptemp) to
prevent a memory leak.

excellent. thank you for the help :)
 
N

N.S. du Toit

N.S. du Toit said:
excellent. thank you for the help :)

in the same veign, is it possible to find these types of errors using gdb,
and how would one go about doing that?

thank you
 
R

Richard Heathfield

N.S. du Toit said:
in the same veign, is it possible to find these types of errors [he
means seg faults] using gdb, and how would one go about doing that?

man gdb has to be worth a try, doesn't it?

gdb is, however, a specific software tool, and its behaviour is not defined
by the C language. You could profitably raise the question in
comp.os.linux.development.apps or comp.unix.programmer - but in your own
interest, I recommend that you investigate the man page, Google, and lots
of other resources first, so that you can at least show that you've /tried/
to find out on your own.
 
K

Keith Thompson

Pieter Droogendijk said:
int isIP(const char *ip) {

char* segment;
int segmentcount = 0;
char iptemp[3+1+3+1+3+1+3+1]; /* Ip address won't get longer
than this */
// we mustn't change the IP pointer (strtok changes content)
memcpy(iptemp, ip, strlen(ip)+1 );

I'm not sure this is a safe assumption, even for valid IP addresses (I
don't know whether extra leading 0s are allowed). In any case, given
the name of the function, it has to allow for strings that *aren't*
valid IP addresses.

Instead, I suggest (as I think someone else has done):

char *iptemp = malloc(strlen(ip) + 1);

with a check that malloc() succeeded and a free() before leaving the
function.

Also, it probably makes more sense to use strcpy() than memcopy().
 
A

Alexander Bartolich

begin Keith Thompson:
Instead, I suggest (as I think someone else has done):

char *iptemp = malloc(strlen(ip) + 1);

with a check that malloc() succeeded and a free() before leaving the
function.

Also, it probably makes more sense to use strcpy() than memcopy().

Why do people use a low-level language like C when they absolutely
don't care about efficiency? What is so seductive about calling strlen
over and over again?

size_t size = strlen(ip) + 1;
char *iptemp = malloc(size);
memcpy(iptemp, ip, size);

Anyway, given the specific problem we can assume an upper limit for
the required buffer size. The input might exceed that limit, but that
is an indication of error.
A buffer on the stack combined with strncpy or snprintf will do.
 
P

Pieter Droogendijk

Pieter Droogendijk said:
int isIP(const char *ip) {

char* segment;
int segmentcount = 0;
char iptemp[3+1+3+1+3+1+3+1]; /* Ip address won't get longer
than this */
// we mustn't change the IP pointer (strtok changes content)
memcpy(iptemp, ip, strlen(ip)+1 );

I'm not sure this is a safe assumption, even for valid IP addresses (I
don't know whether extra leading 0s are allowed). In any case, given
the name of the function, it has to allow for strings that *aren't*
valid IP addresses.

Yes, and valid ip addresses will fit into a buffer of 15, plus a terminator.
If leading zeroes are allowed in an ip address, then a malloc() will be useful,
however that'll induce painful (or drastically different) code later on in the
source, since said buffer should be freed before returning. I merely solved the
problem with a minimum of code change :p
 
K

Keith Thompson

Pieter Droogendijk said:
Pieter Droogendijk said:
int isIP(const char *ip) {

char* segment;
int segmentcount = 0;
char iptemp[3+1+3+1+3+1+3+1]; /* Ip address won't get longer
than this */

// we mustn't change the IP pointer (strtok changes content)
memcpy(iptemp, ip, strlen(ip)+1 );

I'm not sure this is a safe assumption, even for valid IP addresses (I
don't know whether extra leading 0s are allowed). In any case, given
the name of the function, it has to allow for strings that *aren't*
valid IP addresses.

Yes, and valid ip addresses will fit into a buffer of 15, plus a
terminator. If leading zeroes are allowed in an ip address, then a
malloc() will be useful, however that'll induce painful (or
drastically different) code later on in the source, since said
buffer should be freed before returning. I merely solved the problem
with a minimum of code change :p

If you're going to assume that the argument is already a valid IP
address, an even simpler solution is:

int isIP(const char *ip) { return 1; }

If you're not willing to make that assumption, I'm afraid you're just
going to have to deal with the possibility that the string is longer
than 15 characters.

I've always found calling free() to be much less painful than nasal
demons.
 
N

no_name

Just having a bit of trouble programming with C under FreeBSD 5.1 using the
gcc compiler. I'm a bit new to C so my apologies if the answer to my
question appear obvious :)

Basically I've written a function that will check whether a string is an ip
address (see the function isIP below). During my attempt at debugging this
problem I inserted a printf statement before the return command from the
statement, and also a printf statement after the function's call.
Strangely, the last printf in the function prints, but not the printf after
the function has been called. So somewhere something causes a problem
during the attempt at exiting the function.

FreeBSD prints:
Segmentation fault (core dumped)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define uc unsigned char

/* if a ip address= (space-'\n')+number+(space-'\n').
(space-'\n')+number+(space-'\n').(space-'\n')+number+(space-'\n').
(space-'\n')+number+(space-'\n') */
int is_ip(char* a, int* v)
{char i, *b;
unsigned long ak;

for(i=0; i<4; ++i, ++a) /* 0.1.2. 3*/
{while(isspace( (uc) *a) && *a!='\n') ++a;
if(!isdigit(*a))
return 0;
ak=strtoul(a, &b, 10);
if(ak>255)
return 0;
if(i==3)
{a=b;
if(!isspace( (uc) *a ) && *a!='\0' )
return 0;
v=ak;
return 1;
}
for( a=b; isspace( (uc) *a ) && *a!='\n'; ++a);
if(*a!='.')
return 0;
v= ak;
}
}

int main(void)
{char a[] ="255 . 255 . 255. 255";
int v[4]={0,0,0,0}, r;
while(*a!='n')
{r=is_ip(a, v);
printf("%d: %d.%d.%d.%d\n", r, v[0], v[1], v[2], v[3] );
printf("continuare? number.number.number.number/n ");
fflush(stdout);
if(fgets(a, sizeof(a), stdin)==NULL) return 0;
}
return 0;
}
 
B

Barry Schwarz

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define uc unsigned char

/* if a ip address= (space-'\n')+number+(space-'\n').
(space-'\n')+number+(space-'\n').(space-'\n')+number+(space-'\n').
(space-'\n')+number+(space-'\n') */
int is_ip(char* a, int* v)
{char i, *b;
unsigned long ak;

for(i=0; i<4; ++i, ++a) /* 0.1.2. 3*/
{while(isspace( (uc) *a) && *a!='\n') ++a;
if(!isdigit(*a))
return 0;
ak=strtoul(a, &b, 10);
if(ak>255)
return 0;
if(i==3)
{a=b;
if(!isspace( (uc) *a ) && *a!='\0' )

If,during the fgets call, the user enters 1.1.1.1 and then presses
enter, a will contain '1', '.', '1', '.', '1', '.', '1', '\n', and
'\0'. This will cause the second expression to be true and lead you
to reject a valid address.
return 0;
v=ak;
return 1;


If the user enters 1.1.1.1 followed by a space and another 1, you will
accept this invalid IP address as valid.
}
for( a=b; isspace( (uc) *a ) && *a!='\n'; ++a);
if(*a!='.')
return 0;
v= ak;
}
}

int main(void)
{char a[] ="255 . 255 . 255. 255";
int v[4]={0,0,0,0}, r;
while(*a!='n')
{r=is_ip(a, v);
printf("%d: %d.%d.%d.%d\n", r, v[0], v[1], v[2], v[3] );
printf("continuare? number.number.number.number/n ");
fflush(stdout);
if(fgets(a, sizeof(a), stdin)==NULL) return 0;
}
return 0;
}




<<Remove the del for email>>
 
N

no_name

^^^^^^^^^^NO space+'\0'
If,during the fgets call, the user enters 1.1.1.1 and then presses
enter, a will contain '1', '.', '1', '.', '1', '.', '1', '\n', and
'\0'. This will cause the second expression to be true and lead you
to reject a valid address.
NO
1: 255.255.255.255
|>[this ends with ,255,'\0', seems ok]
continuare? number.number.number.number/n 1.1.1.1
1: 1.1.1.1
|>[seems ok this ends with '\n\0' ?]
continuare? number.number.number.number/n 23.33 . 45 . 1 q
1: 23.33.45.1
continuare? number.number.number.number/n 23.33 . 45 . 1q
0: 23.33.45.1
continuare? number.number.number.number/n 23.33 . 45 .
19999999922222222
0: 23.33.45.1
continuare? number.number.number.number/n 0: 23.33.45.1
|> here the problem?
continuare? number.number.number.number/n
8888888888888888888888888888.99999
0: 23.33.45.1
continuare? number.number.number.number/n 0: 23.33.45.1
continuare? number.number.number.number/n

Are there problems with big numbers?


Thank you and bye
 

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,756
Messages
2,569,535
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top