Thread: fscanf causes a SEGMENTATION FAULT

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    182

    fscanf causes a SEGMENTATION FAULT

    In the main body
    fscanf( tfPtr, "%d %f", &accountNum, &balance );
    is causing a SEGMENTATION FAULT. What is really throwing me off is the fact that I use the same fscanf function in getTransaction() with no problems at all. Any ideas on what might be wrong?


    Code:
    #include <stdio.h>
    
    int match( int account, FILE *fPtr );
    float getTransaction( int account, FILE *transaction );
    
    
    
    int main()
    {
    	FILE *ofPtr;
    	FILE *tfPtr;
    	FILE *nfPtr;
    
    	int accountNum;
    	char *name;
    	float balance;
    
    	ofPtr = fopen( "oldmast.dat", "r" );
    	tfPtr = fopen( "trans.dat", "r" );
    	nfPtr = fopen( "newmast.dat", "w" );
    
    /*   INCORRECT USE OF feof() it runs last member twice  */
    
    	while ( !feof( ofPtr ) ) {
    		fscanf( ofPtr, "%d %s %f", &accountNum, name, &balance );
    		printf( "%d\n", accountNum );
    		balance += getTransaction( accountNum, tfPtr );
    		printf( "%d %s %.2f\n", accountNum, name, balance );
    		fprintf( nfPtr, "%d %s %.2f\n", accountNum, name, balance );
    	}
    
    	rewind( tfPtr );
    	rewind( ofPtr );
    
    
    
    
    	while ( !feof( tfPtr ) ) {
    /*   This fscanf is causing a segmentation error
         -----------------------------------------------------------*/
    		fscanf( tfPtr, "%d %f", &accountNum, &balance );
    
    /*	
    		if ( !match( accountNum, ofPtr ) ) {
    			printf( "There is no match for this account in the oldmaster file\n" );
    		}
    */
    	}
    
    
    
    /*    This is a test of the match function  */
    	printf( "%d\n", match( 1, ofPtr ) );
    
    
    /*   CLOSING ANY FILE IS CAUSING A SEGMENTATION FAULT    */
    //	fclose( ofPtr );
    //	fclose( tfPtr );
    //	fclose( nfPtr );
    
    	return 0;
    }
    
    
    
    
    float getTransaction( int account, FILE *fPtr )
    {
    	int accountNum = 0;
    	float dollarAmount = 0;
    
    	rewind( fPtr );
    	while( !feof( fPtr ) ) {
    		fscanf( fPtr, "%d %f", &accountNum, &dollarAmount );
    
    		if ( accountNum == account ) {
    			rewind( fPtr );
    			return dollarAmount;
    		}
    	}	
    
    	rewind( fPtr );
    	return 0.0;
    }
    
    
    
    
    /*  ONLY WORKS WITH ofPtr  */
    int match( int account, FILE *fPtr )
    {
    	int accountNum = 0;
    //	float dollarAmount = 0.0;
    	float balance;
    	char *name;
    
    	rewind( fPtr );
    	while ( !feof( fPtr ) ) {
    		fscanf( fPtr, "%d %s %f", &accountNum, name, &balance );
    
    		if ( account == accountNum ) {
    			rewind( fPtr );
    			return 1;
    		}
    	}
    
    	rewind( fPtr );
    	return 0;
    }
    Last edited by yougene; 12-28-2008 at 09:06 PM.

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Did you run it through a debugger to pinpoint the offending line?
    Compile the source with the -g flag; run it through gdb; and post its output here.

  3. #3
    Registered User
    Join Date
    Dec 2008
    Location
    Loch Ness
    Posts
    6
    Hi yougene...

    About your segmentation fault :

    You haven't allocated memory for char *name. Allocate memory for it and your seg problem is solved.
    It worked fine for me.

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    182
    I haven't tried any of these suggestions yet but I wanted to point out that I had a major brain fart. The offending fscanf is in the match() function.

    Is it ever too early to start learning GDB?


    What do you mean by allocate memory to *name? Point it to an existing char array?


    Thank you for the input

  5. #5
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Well, not necesserily. You can do this:

    Code:
    char name[some_size]; //static allocation
    char* name = malloc(some_size); //dynamic allocation
    Why you need this? I am glad you asked. Because fscanf will copy the string read to where char* name points. Which is nowhere (some falsely think New Jersey). So where will the string be copied to?

    (Well, char* name actually points to somewhere since it has a value, but somewhere that you don't have access, since you haven't allocated that memory. So you get a seg fault)

  6. #6
    Registered User
    Join Date
    Dec 2008
    Location
    Loch Ness
    Posts
    6
    simplest way is to add " name = malloc ( SIZE ) " in ur code...

    SIZE depends on your requirement of the number of characters in a name...

    Or as you said "point it to a char array".....That would also work...

  7. #7
    Registered User
    Join Date
    May 2006
    Posts
    182
    Ahh gotchya. Well I haven't gotten to using malloc yet but I see your point.

    Some confusion does come up though. You see I used the exact same fscanf statement and empty "name" pointer in my main body no problem. Yet when I use this in the match() function it throws a FAULT. Why throw a FAULT in one instance and not the other?

  8. #8
    Registered User
    Join Date
    Dec 2008
    Location
    Loch Ness
    Posts
    6
    It will throw a problem in the main function as well.

    Just follow these steps :

    1 . gcc -g "your_c_file"

    2. gdb a.out

    3. b main

    4. r

    5. continuosly press enter and follow the code execution. it will show you the line where u will get the seg fault.

  9. #9
    Registered User
    Join Date
    May 2006
    Posts
    182
    Thanks. The main body actually works fine. I've run the program without any match function no problem.

    I reach a breakpoint at fopen. Pressing enter doesn't go on to the next command though. It does nothing.

  10. #10
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by yougene View Post
    Ahh gotchya. Well I haven't gotten to using malloc yet but I see your point.

    Some confusion does come up though. You see I used the exact same fscanf statement and empty "name" pointer in my main body no problem. Yet when I use this in the match() function it throws a FAULT. Why throw a FAULT in one instance and not the other?
    Well, if you read my parenthesis, name will always have a value. It will just contain a value that you don't know. The value will be a memory address that your program won't have access to. It can point for example in memory which another program uses.
    Thus, the behaviour is undefined. It might work in some occasions because the memory it points to might be within the memory the program is allowed to write/read. Everytime a program starts it is allowed to write on some specific memory. But that might change with every execution, so even if it works it might cause problems later. Or it might overwrite one something in your own program....

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    182
    Ahh crystal clear.

    Thanks everyone. It's been educational.

  12. #12
    Registered User
    Join Date
    May 2006
    Posts
    182
    On a related note, does anyone know why closing the files with fclose( ) is also giving me segmentation faults?

  13. #13
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Maybe the pointer is NULL?
    fopen return NULL when there is an error. You should check for that occasion before doing anything else. Like:
    Code:
    filePointer = fopen(...);
    if (filePointer == NULL) {
        printf("Error");
        exit(1);
    }
    If it is NULL then it might cause a seg fault, since it won't actually point to a file

  14. #14
    Registered User
    Join Date
    May 2006
    Posts
    182
    It was actually related to using the "name" character pointer. Thanks!

  15. #15
    Registered User
    Join Date
    Dec 2008
    Location
    Loch Ness
    Posts
    6
    About the feof call reading the last line twice, its not the reading the last line for the second time.
    If you want to test for feof then it should be scanned first. For your code its scanning it for the first time and the values are stored in the variables. For the second its encountering an EOF but it will exit only when it loops again and hence it uses the already stored values (after the first iteration) the second time.

    Hence what u should do is :
    Code:
    fptr = fopen("some_file",flag);
    
    while(1)
    {
              fscanf(fptr,args.....);
              if(feof(fptr))
                              break;
               /* your code */
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  2. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  3. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  4. Annoying Segmentation Fault
    By Zildjian in forum C++ Programming
    Replies: 7
    Last Post: 10-08-2004, 02:07 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM