Beginner requesting help - Segmentation fault

F

Fra-it

Hi everybody,
I'm trying to make the following code running properly, but I can't get
rid of the "SEGMENTATION FAULT" error message when executing.
Reading some messages posted earlier, I understood that a segmentation
fault can occur whenever I declare a pointer and I leave it
un-initialized.
So I thought the problem here is with the (const char *)s in the stuct
flightData (please note that I get the same fault declaring as char *
the members of struct flightData), but I can't figure out why.
Please also note that I've declared struct flightData members as char *
instead of char vectors, because I can't assume a value for the maximum
lenght of town names in flights.dat.

Could someone kindly explain the reason for I get the segmentation
fault, and suggest a way to make the program run properly?

Many thanks
Fra

The source code was compiled with GCC 3.3.5 (both with and without
-ansi option: the result is always the same) under Linux Knoppix 3.7
Live (kernel 2.6.9)

*** Here is the content of flights.dat:

Madrid Roma AA
Paris London UA
Milano Roma AZ
Milano New_York AZ
Berlin Milano LA
Roma Paris AZ


*** Here is the source code of fly3.c:

#include <stdio.h>
#include <string.h>

#define DEBUG

struct flightData {
const char * takeoffTown;
const char * landingTown;
const char * code;
};

/* ...omitted function prototypes... */

int main( int argc, const char *argv[] )
{
struct flightData flight;
FILE *flightsFPtr, *takeoffsFPtr, *landingsFPtr, *companiesFPtr;

if ( argc != 3 ) {
printf( "Usage: fly3 flights.dat Town - Aborting program fly3\n"
);
return 0;
}
if ( (flightsFPtr = fopen( argv[1], "r" )) == NULL ) {
printf( "Cannot open file %s - Aborting program fly3\n" );
return 0;
}

#ifdef DEBUG
printf( "Opening output files...\n" );
#endif
takeoffsFPtr = fopen( "takeoffs.dat", "w" );
landingsFPtr = fopen( "landings.dat", "w" );
companiesFPtr = fopen( "companies.dat", "w" );

#ifdef DEBUG
printf( "Scanning file %s...\n", argv[1] );
#endif
while ( !feof(flightsFPtr) ) {
#ifdef DEBUG
printf( "Reading %s...\n", argv[1] );
#endif
fscanf( flightsFPtr, "%s%s%s", &flight.takeoffTown,
&flight.takeoffTown, &flight.code );

#ifdef DEBUG
/* NEXT THREE LINES ARE FOR DEBUGGING PURPOSES */
printf( "I've read file %s...\n", argv[1] );
printf( "Town entered by user: %s\n", argv[2] );
printf( "I've read takeoff from: %s\n", flight.takeoffTown );
/* HERE I GET SEGMENTATION FAULT IF DEBUGGING*/
#endif

/* testing if the town name entered by user matches the name
stored in flight.takeoffTown */
if ( strcmp(flight.takeoffTown, argv[2]) == 0 ) { /* HERE I GET
SEGMENTATION FAULT IF NOT DEBUGGING */
#ifdef DEBUG /* COULDN'T EVER EXECUTE FROM THIS LINE ON... =(
*/
printf( "Writing on takeoffs file...\n" );
#endif
writeData( takeoffsFPtr, flight );
if ( stringPresence( companiesFPtr, flight.code ) == 0 ) {
#ifdef DEBUG
printf( "Writing on companies file...\n" );
#endif
fprintf( companiesFPtr, "%s\n", flight.code );
}

/* *** ...omitted the remaining code... *** */


*** and finally the output running the executable:

$ fly3 flights.dat Milano
Opening output files...
Scanning file flights.dat...
Reading flights.dat...
I've read file flights.dat...
Town entered by user: Milano
Segmentation fault
$
 
D

David Shin

You didn't allocation space for takeoffTown, landingTown, and code
before using them.

struct flightData {
const char * takeoffTown;
const char * landingTown;
const char * code;
};
 
K

Keith Thompson

Fra-it said:
struct flightData {
const char * takeoffTown;
const char * landingTown;
const char * code;
};

Since you want to initialize the strings these members point to, why
did you declare them as const?

[...]
fscanf( flightsFPtr, "%s%s%s", &flight.takeoffTown,
&flight.takeoffTown, &flight.code );

The "%s" fscanf format expects a char*. You're passing a char** (the
address of a (const) char* object). This invokes undefined behavior;
the most likely consequence is that the string overwrites the pointer
and (if it's longer than sizeof(char*) bytes) some of the memory
following it.

You need to pass a char* to fscanf(), *and* you need to allocate
enough space to hold the input string. You can specify a maximum
field width to limit the size of the input.

Also, you probably didn't want to specify flight.takeoffTown twice.
 
S

Sandeep

I'm trying to make the following code running properly, but I can't get
You should now be thinking about tools like a debugger ( eg: gdb ). You
should compile your program with -g option and then put a break at
main. then single step through the code to see where the segmentation
fault is happening.
Analysing code carefully is another option. You must use pointers
carefully when:
1) You are allocating/deallocating memory
2) Assigning one pointer to another
3) Passing a pointer to a function - And when returning it

Bugs are bound to remain - My take is , use a debugger and take a
"defensive" approach to programming - check for NULL pointers wherever
you think is critical .
 
F

Fra-it

Thank you all for pointing out the logical and syntax flaw in my
code... I'm going to learn using a debugger... I think I should have
done it anyway...

I hope I've replied correctly (I used "show options" --> "reply"
instead of the reply link at the bottom of the last message)

Good day
Fra
 
J

James McIninch

<posted & mailed>

A segmentation fault occurs when you attempt to access a section of memory
that it can't (because it doesn't exist) or to which is doesn't have
permission.

In this particular case, you never initialize the pointers in your data
structure to point to a writable segment of memory (you'd use malloc() to
do this). Since the pointers don't point to anything, when you attempt to
write data into them using fscanf(), the error occurs.


Fra-it said:
Hi everybody,
I'm trying to make the following code running properly, but I can't get
rid of the "SEGMENTATION FAULT" error message when executing.
Reading some messages posted earlier, I understood that a segmentation
fault can occur whenever I declare a pointer and I leave it
un-initialized.
So I thought the problem here is with the (const char *)s in the stuct
flightData (please note that I get the same fault declaring as char *
the members of struct flightData), but I can't figure out why.
Please also note that I've declared struct flightData members as char *
instead of char vectors, because I can't assume a value for the maximum
lenght of town names in flights.dat.

Could someone kindly explain the reason for I get the segmentation
fault, and suggest a way to make the program run properly?

Many thanks
Fra

The source code was compiled with GCC 3.3.5 (both with and without
-ansi option: the result is always the same) under Linux Knoppix 3.7
Live (kernel 2.6.9)

*** Here is the content of flights.dat:

Madrid Roma AA
Paris London UA
Milano Roma AZ
Milano New_York AZ
Berlin Milano LA
Roma Paris AZ


*** Here is the source code of fly3.c:

#include <stdio.h>
#include <string.h>

#define DEBUG

struct flightData {
const char * takeoffTown;
const char * landingTown;
const char * code;
};

/* ...omitted function prototypes... */

int main( int argc, const char *argv[] )
{
struct flightData flight;
FILE *flightsFPtr, *takeoffsFPtr, *landingsFPtr, *companiesFPtr;

if ( argc != 3 ) {
printf( "Usage: fly3 flights.dat Town - Aborting program fly3\n"
);
return 0;
}
if ( (flightsFPtr = fopen( argv[1], "r" )) == NULL ) {
printf( "Cannot open file %s - Aborting program fly3\n" );
return 0;
}

#ifdef DEBUG
printf( "Opening output files...\n" );
#endif
takeoffsFPtr = fopen( "takeoffs.dat", "w" );
landingsFPtr = fopen( "landings.dat", "w" );
companiesFPtr = fopen( "companies.dat", "w" );

#ifdef DEBUG
printf( "Scanning file %s...\n", argv[1] );
#endif
while ( !feof(flightsFPtr) ) {
#ifdef DEBUG
printf( "Reading %s...\n", argv[1] );
#endif
fscanf( flightsFPtr, "%s%s%s", &flight.takeoffTown,
&flight.takeoffTown, &flight.code );

#ifdef DEBUG
/* NEXT THREE LINES ARE FOR DEBUGGING PURPOSES */
printf( "I've read file %s...\n", argv[1] );
printf( "Town entered by user: %s\n", argv[2] );
printf( "I've read takeoff from: %s\n", flight.takeoffTown );
/* HERE I GET SEGMENTATION FAULT IF DEBUGGING*/
#endif

/* testing if the town name entered by user matches the name
stored in flight.takeoffTown */
if ( strcmp(flight.takeoffTown, argv[2]) == 0 ) { /* HERE I GET
SEGMENTATION FAULT IF NOT DEBUGGING */
#ifdef DEBUG /* COULDN'T EVER EXECUTE FROM THIS LINE ON... =(
*/
printf( "Writing on takeoffs file...\n" );
#endif
writeData( takeoffsFPtr, flight );
if ( stringPresence( companiesFPtr, flight.code ) == 0 ) {
#ifdef DEBUG
printf( "Writing on companies file...\n" );
#endif
fprintf( companiesFPtr, "%s\n", flight.code );
}

/* *** ...omitted the remaining code... *** */


*** and finally the output running the executable:

$ fly3 flights.dat Milano
Opening output files...
Scanning file flights.dat...
Reading flights.dat...
I've read file flights.dat...
Town entered by user: Milano
Segmentation fault
$
 
M

Mike Wahler

Fra-it said:
Thank you all for pointing out the logical and syntax flaw in my
code... I'm going to learn using a debugger... I think I should have
done it anyway...

I think doing so will cause you to truly
recognize the value of a debugger.
I hope I've replied correctly

No, you didn't.
(I used "show options" --> "reply"
instead of the reply link at the bottom of the last message)

I don't use google groups, so you'll need to figure it
out yourself -- but what you failed to do was include
attribution (who wrote what you're replying to) and
context (enough of the text to which you're replying
that someone can read your message and understand the
relevant portions of the conversation without referring
to other messages in the thread.) Use this message from
me as an example.

But thanks for trying and caring. :)

-Mike
 
C

Christopher Benson-Manica

Mike Wahler said:
I don't use google groups, so you'll need to figure it
out yourself

(Or just read Keith's succinct how-to, which follows for OP's benefit.)

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
M

Mike Wahler

Christopher Benson-Manica said:
(Or just read Keith's succinct how-to, which follows for OP's benefit.)

Of course. That's one of the avenues of 'figure it out'. :)

-Mike
 
K

Keith Thompson

Christopher Benson-Manica said:
(Or just read Keith's succinct how-to, which follows for OP's benefit.)

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

Which is exactly what he said he did. Either he didn't do what he
said (presumably an honest mistake), or he used the proper "Reply"
button and then deleted the quoted text and attribution. (Or Google
is now even more broken than it was before.)
 
J

Jordan Abel

Which is exactly what he said he did. Either he didn't do what he
said (presumably an honest mistake), or he used the proper "Reply"
button and then deleted the quoted text and attribution. (Or Google
is now even more broken than it was before.)

Possibly he thought that having to reply one way instead of another
was just an arbitrary requirement, or that if he used the wrong
button he wouldn't be seen at all, and didn't understand that the
reason was so that text would be quoted.
 
F

Fra-it

Keith said:
Which is exactly what he said he did. Either he didn't do what he
said (presumably an honest mistake), or he used the proper "Reply"
button and then deleted the quoted text and attribution. (Or Google
is now even more broken than it was before.)

Yes, I clicked "Show options", then "Reply" and deleted all the quoted
text...
indeed mine was simply a general thanks to all people who gave me their
suggestions.
By the way, thanks to you all I'm rearranging the code of fly3.c this
weekend, learning something about malloc() and beginning to learn to
use a compiler...
Greets
Fra-it
 
K

Keith Thompson

Old Wolf said:
Looks like you need to expand your advice block a bit, Keith :)

No, I think this was an unusual case. The followup in question was a
general reply to everyone who had replied; there probably wasn't any
context in the immediate parent article that was necessary for
Fra-it's followup to be understandable. It was a problem only because
it *looked* like the usual context-free Google followup.

(It's not clear that a general "thanks, everyone" followup is really
necessary, but I won't get into that.)

If you're going to post a followup that really doesn't depend on the
parent article, it's probably a good idea to include some context
anyway, at least an attribution line and a "[snip]" -- not because
it's really necessary, but because it avoids confusion.
 

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

Similar Threads

segmentation fault. 8
Segmentation fault error 12
Segmentation fault 37
segmentation fault sometimes 6
segmentation fault 8
Unpredictable segmentation fault 7
Segmentation Fault 29
Segmentation fault 10

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top