By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
426,034 Members | 1,714 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 426,034 IT Pros & Developers. It's quick & easy.

Beginner requesting help - Segmentation fault

P: n/a
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
$

Nov 15 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
You didn't allocation space for takeoffTown, landingTown, and code
before using them.

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

Nov 15 '05 #2

P: n/a
"Fra-it" <fr***************@yahoo.it> writes:
[...]
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #3

P: n/a
Keith Thompson wrote:
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

Nov 15 '05 #4

P: n/a
Fra-it wrote:
Keith Thompson wrote:
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.


Yes, I clicked "Show options", then "Reply" and deleted all the
quoted text...


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

Nov 15 '05 #5

P: n/a
"Old Wolf" <ol*****@inspire.net.nz> writes:
Fra-it wrote:
Keith Thompson wrote:
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.


Yes, I clicked "Show options", then "Reply" and deleted all the
quoted text...


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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.