2013-09-24 41 views
1

我刪掉了可以工作的代碼,所以下面的代碼不是一個完整的程序,而是一個有問題的部分。使用fscanf時出現分段錯誤,使用valgrind後出現故障調試問題

我在下面的fscanf行上得到了分段錯誤。我添加了每個變量的字符寬度來嘗試修復它,所以我不明白爲什麼它會出現seg錯誤。

我從一個CSV文件讀取到一個結構數組中。

我主要就是這一點:

#include <stdio.h> 
#include <stdlib.h> 

main() 
{ 
    menu(); 
} 

然後menu.c:

#include <stdio.h> 
#include <stdlib.h> 
#include "DatabaseOps.h" 
#include "menu.h" 
#define SIZE 1000 //max size assumed to be 1000 
void menu() 
{ 
    int j, lastID; //keeping track of id numbers used 

    Person* persons; 
    persons = (Person*)malloc(SIZE * sizeof(Person)); /*declaring array of person structs on the heap*/ 

    for(j = 0; j < SIZE; j++) /*initialise all IDs to -1*/ 
     { 
     persons[j].ID = -1; 
     } 

    int option = 1; 
    while (option!=7) 
    { 
     printf("1. Load Database\n"); 
     scanf("%d", &option); 

     switch (option) 
      { 
      case 1: 
      printf("\nLoading Database\n\n"); 
      lastID = loadDb(persons); 
      break; 

      default: 
      printf("Invalid choice, please try again\n\n"); 
      break; 
      } 
    } 
} 

人員在menu.h定義,像這樣:

typedef struct Person 
    { 
    int ID; 
    int salary; 
    int deleted; 
    char salutation[4]; 
    char firstName[21]; 
    char surName[31]; 
    char job[16]; 
    } Person; 

然後是DatabaseOps .c文件導致錯誤:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "DatabaseOps.h" 
#include "menu.h" 

int loadDb(Person *inPersons) //function reads csv file into an array of Employee structs 
    { 
    int i, newID = 0; /*declaring lastID counter to keep track of the last employee ID so that I can increment it when creating a new employee*/ 

    char* fileName = malloc(100 * sizeof(char)); 
    printf("Enter name of CSV file: "); 
    scanf("%99s", fileName); 

    FILE* f = fopen(fileName, "r"); 

    if(f==NULL) /*If the file doesn't exist, return to menu*/ 
     { 
     printf("Error: could not open file\n"); 
     } 

    else 
     { /*the fscanf function uses grouping by commas to seperate the CSV values - [^,]*/ 
     while(fscanf(f, "%d,%3[^,],%20[^,],%30[^,],%15[^,],%d,%d", &inPersons[i].ID, inPersons[i].salutation, inPersons[i].firstName, inPersons[i].surName, inPersons[i].job, &inPersons[i].salary, &inPersons[i].deleted)!=EOF) 
      { 
      newID = inPersons[i].ID; //Keeping track of the last used ID 
      i++; 
      } 
     } 
    fclose(f); 

    return newID; 
    } 

Valgrind的給了我這個錯誤,這我不知道如何解釋:

==19378== Use of uninitialised value of size 4 
==19378== at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so) 
==19378== by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so) 
==19378== by 0x80486E5: loadDb (DatabaseOps.c:25) 
==19378== by 0x80485B5: menu (menu.c:29) 
==19378== by 0x804852E: main (main.c:6) 
==19378== 
==19378== Invalid write of size 4 
==19378== at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so) 
==19378== by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so) 
==19378== by 0x80486E5: loadDb (DatabaseOps.c:25) 
==19378== by 0x80485B5: menu (menu.c:29) 
==19378== by 0x804852E: main (main.c:6) 
==19378== Address 0x9acac288 is not stack'd, malloc'd or (recently) free'd 
==19378== 
==19378== 
==19378== Process terminating with default action of signal 11 (SIGSEGV) 
==19378== Access not within mapped region at address 0x9ACAC288 
==19378== at 0x405A215: _IO_vfscanf (in /lib/libc-2.12.so) 
==19378== by 0x4067368: __isoc99_fscanf (in /lib/libc-2.12.so) 
==19378== by 0x80486E5: loadDb (DatabaseOps.c:25) 
==19378== by 0x80485B5: menu (menu.c:29) 
==19378== by 0x804852E: main (main.c:6) 

回答

3
int i, newID = 0; /*declaring lastID counter to keep track of the last employee ID so that I can increment it when creating a new employee*/ 

i需要被初始化爲0

+0

哇,固定它。簡直不敢相信它是如此簡單。我假設初始化就像初始化線上的所有變量。謝謝。 – Dawson

+0

@ user2368481:您需要將您的編譯器警告起來。用'-std = c99 -pedantic -Wall -Werror'編譯,它會告訴你這樣的事情。 –

+0

我一定會在未來做到這一點。 – Dawson