2010-05-25 36 views
1

對我來說這似乎至少是怪異的......程序運行正常。但是在我第四次調用enter()函數後,出現了分段錯誤!我將不勝感激任何幫助。C-Segment錯誤!

使用下面的函數enter()我想添加用戶命令的數據到列表中。

[代碼的某些部分已經被貼在了我的另一個問題,但我想我應該再次發佈它......因爲它是我現在面臨一個不同的問題。]

/* struct for all the datas that user enters on file*/ 
typedef struct catalog  
{  char short_name[50];      
     char surname[50];      
     signed int amount;      
     char description[1000];    
     struct catalog *next; 
}catalog,*catalogPointer; 

catalogPointer current; 
catalogPointer head = NULL; 

void enter(void) //user command: i <name> <surname> <amount> <description> 

{ 
    int n,j=2,k=0; 
    char temp[1500]; 
    char *short_name,*surname,*description; 
    signed int amount; 

    char* params = strchr(command,' ') + 1; //strchr returns a pointer to the 1st space on the command.U want a pointer to the char right after that space. 
    strcpy(temp, params);    //params is saved as temp. 

    char *curToken = strtok(temp," ");  //strtok cuts 'temp' into strings between the spaces and saves them to 'curToken' 
    printf("temp is:%s \n",temp); 

    printf("\nWhat you entered for saving:\n"); 

    for (n = 0; curToken; ++n)   //until curToken ends: 
    { 
     if (curToken) 
     { short_name = malloc(strlen(curToken) + 1); 
      strncpy(short_name, curToken, sizeof (short_name));  
     } 
     printf("Short Name: %s \n",short_name);    

     curToken = strtok(NULL," ");      
     if (curToken) 
     { surname = malloc(strlen(curToken) + 1); 
      strncpy(surname, curToken,sizeof (surname)); } 
     printf("SurName: %s \n",surname); 

     curToken = strtok(NULL," ");      
     if (curToken) 
     { //int * amount= malloc(sizeof (signed int *)); 
      char *chk;      
      amount = (int) strtol(curToken, &chk, 10);  

      if (!isspace(*chk) && *chk != 0)    
        fprintf(stderr,"Warning: expected integer value for amount, received %s instead\n",curToken); 
     } 
     printf("Amount: %d \n",amount); 
     curToken = strtok(NULL,"\0");     
     if (curToken) 
     { description = malloc(strlen(curToken) + 1); 
      strncpy(description, curToken, sizeof (description)); 
     } 
     printf("Description: %s \n",description); 
     break; 
    } 

    if (findEntryExists(head, surname,short_name) != NULL)    //call function in order to see if entry exists already on the catalog 
     printf("\nAn entry for <%s %s> is already in the catalog!\nNew entry not entered.\n",short_name,surname); 
    else 
    { 
     printf("\nTry to entry <%s %s %d %s> in the catalog list!\n",short_name,surname,amount,description); 
     newEntry(&head,short_name,surname,amount,description); 
     printf("\n**Entry done!**\n"); 
    } 
    // Maintain the list in alphabetical order by surname. 


} 

catalogPointer findEntryExists (catalogPointer head, char num[],char first[]) 
{ catalogPointer p = head; 
    while (p != NULL && strcmp(p->surname, num) != 0 && strcmp(p->short_name,first) != 0)  
    { p = p->next; } 
    return p; 
} 

catalogPointer newEntry (catalog** headRef,char short_name[], char surname[], signed int amount, char description[]) 
{ 
    catalogPointer newNode = (catalogPointer)malloc(sizeof(catalog)); 
    catalogPointer first; 
    catalogPointer second; 
    catalogPointer tmp; 
    first=head; 
    second=NULL; 

    strcpy(newNode->short_name, short_name);   
    strcpy(newNode->surname, surname); 
    newNode->amount=amount; 
    strcpy(newNode->description, description); 

    while (first!=NULL)      
    {  if (strcmp(surname,first->surname)>0) 
      second=first; 
     else if (strcmp(surname,first->surname)==0) 
      { 
       if (strcmp(short_name,first->short_name)>0) 
        second=first; 
      } 
     first=first->next; 
    } 
    if (second==NULL) 
    {  newNode->next=head; 
     head=newNode; 
    } 
    else        //SEGMENTATION APPEARS WHEN IT GETS HERE! 
    {  tmp=second->next; 
      newNode->next=tmp; 
      first->next=newNode; 
    } 
} 

UPDATE : 只有SegFault在InsertSort()函數的'else'循環上時纔會出現。 我觀察到,當我試圖放在它後面的列表名稱上時出現了分段錯誤。 例如,如果在列表中是否存在:

[名稱:B姓:B的含量:6說明:B] [名:C姓:C量:5說明:C] [名稱:d姓: d名稱:d]數量:4描述:d] [名稱:e姓:e數量:3說明:e] [產品名稱:g姓:g數量:2說明:g] [產品名稱:x產品名稱: :X]

和我把:「XZ 77格格」裏有一個分割 但如果我把「XA 77格格」,它繼續正常....

+0

請提供有關崩潰的更多詳細信息 - 特別是代碼中哪些地方最有用。也請使用此作爲參考,如果它會幫助:http://stackoverflow.com/questions/2588853/the-community-driven-gdb-primer – fbrereto 2010-05-25 16:45:04

+0

其中是命令定義?而且,你正在泄漏內存而沒有釋放你malloc的東西。 – 2010-05-25 16:47:16

+0

很可能你正在寫一個數組的末尾...... – Goz 2010-05-25 16:47:26

回答

4

不能發佈到評論,所以這裏有雲:

while (first!=NULL) { //-> this loop can exit ONLY with 'first' being NULL 
    if (strcmp(surname,first->surname)>0) 
     second=first; 
    else if (strcmp(surname,first->surname)==0) { 
     if (strcmp(short_name,first->short_name)>0) 
     second=first; 
    } 
    first=first->next; 
    } 
    if (second==NULL) {  
    newNode->next=head; 
    head=newNode; 
    } 
    else { 
    tmp=second->next; 
    newNode->next=tmp; 
    first->next=newNode; // first used (but it's NULL!) 
    } 

換句話說,如果發現符合循環內的條件,並設置「第二」的任何條目程序將會崩潰。 (這會觸發列表中的「添加」)。

OK了〜沒有時間等待答案:O),在「內經」「第二」改變代碼這一點,你想進入的情況下:

if (second==NULL) {  
    newNode->next=head; 
    head=newNode; 
    } 
    else { 
    newNode->next=second->next; 
    second->next=newNode; 
    } 

解釋(S是「第二」 N'newNode',AB只是列表中的一些存在條目):

initial: 
     N 

    A -> S -> B 

first assignment: 
     N ---\ 
      | 
      v 
    A -> S -> B 

second assignment: 

     N ---\ 
    ^ | 
     | v 
    A -> S B 

and thus: 
    A-> S -> N -> B 
+0

現在的問題是 - 你想在這種情況下插入新條目?在'第二'之後猜測? – MaR 2010-05-25 18:38:24

+0

謝謝!這是正確的! – FILIaS 2010-05-25 18:53:37

4

不知道是什麼導致ŧ他的錯誤,但我沒有看到這種糟糕的模式:

char *short_name; 
short_name = malloc(strlen(curToken) + 1); 
strncpy(short_name, curToken, sizeof (short_name)); 

sizeof(short_name)將永遠同樣的事情(4通常爲32個平臺和8個64位平臺),所以是不是在這裏使用正確的值。你應該這樣做:

strncpy(short_name, curToken, strlen(curToken) + 1); 
+1

由於段錯誤發生在試圖複製以這種方式「初始化」的字符串時,這可能是問題。我會認爲這個printf會顯示這個... – 2010-05-25 17:10:24

+0

@R Samuel Klatchko。問題依舊。請參閱更新後的文章 – FILIaS 2010-05-25 17:13:09

+0

@每個人當我添加那些他們在列表上不可用的元素時,SegFault就會出現!所以我認爲錯誤是在輸入()函數 – FILIaS 2010-05-25 17:27:14

1

使用像valgrind這樣的問題來找到這樣的問題。

+0

@twk後:錯誤對不起,我不知道它是什麼 – FILIaS 2010-05-25 17:03:03

+0

@FILIaS添加了指向套件@twk的鏈接。 – 2010-05-25 17:11:22

+0

Thanx既ü,但作爲初學者我不知道如何使用它 – FILIaS 2010-05-25 17:28:50

0

從while循環中脫離需要首先爲空。在您嘗試首先訪問的else語句中。

+0

所以我需要首先用null初始化?但是在其他情況下會發生什麼? – FILIaS 2010-05-25 18:41:28

+1

您可以檢查first-> next是否爲null,如果是,請不要先指定first-> next,然後簡單地跳出while循環。儘管基於其他註釋和通用代碼,但是當您的第二個!= NULL或第一個== NULL時,您的意圖似乎是打破循環。無論你想在最後的else中重寫代碼。 – Dale 2010-05-25 18:55:36