2014-12-02 106 views
0

在此程序中,我插入從列表中的文件中讀取的值。在頭有柄從文件中分配列表時出現分段錯誤

dizionario.h

typedef struct dizionario* DIZ; 

lista.h

typedef struct lista* LISTA; 

在主我調用該函數init_diz返回一個指針DIZ

main.c

FILE *fp; 
DIZ d; 

...

if((d=init_diz(&fp))==NULL) 
    return EXIT_FAILURE; 

dizionario.c

struct dizionario{ 
    LISTA head; 
    LISTA tail; 
}; 

DIZ init_diz(FILE **f) 
{ 
    DIZ nuovo; 
    nuovo=(DIZ)malloc(sizeof(struct dizionario)); 
    if(nuovo==NULL) 
     return nuovo; 
    if(!alloc_lista(&f, &(nuovo->head), &(nuovo->tail))) 
     return NULL; 
    return nuovo; 
} 

lista.c

struct lista{ 
    LISTA next; 
    LISTA prev; 
    char codex[N+1]; 
    char nome[MAXWORD+1]; 
    char cognome[MAXWORD+1]; 
    char data[N+1]; 
}; 
int alloc_lista(FILE ***fil, LISTA *testa, LISTA *coda) 
{ 
    LISTA nuovo, prec=NULL; 
    for(nuovo=*testa; !feof(**fil); nuovo=nuovo->next){ 
     nuovo=(LISTA)malloc(sizeof(struct lista)); 
     if(nuovo==NULL) 
      return 0; 
     fscanf(**fil, "%s%s%s%s", nuovo->codex, nuovo->nome, nuovo->cognome, nuovo->data); 
     nuovo->next=NULL; 
     nuovo->prev=prec; 
     prec=nuovo; 
    } 
*coda=prec; 
return 1; 
} 

當我遍歷列表T中Ô刪除節點i採取SIGSEGV

的main.c

eliminazione(d); 

dizionario.c

void eliminazione(DIZ diz) 
{ 
    elimina((diz)->head); 
} 

lista.c

void elimina(LISTA testa) 
{ 
    LISTA h; 
    char codice[N+1]; 
    printf("inserisci il codice dell'elemento da eliminare: "); 
    scanf("%s", codice); 
    for(h=testa; h!=NULL; h=h->next){ 
     if(strcmp(h->codex, codice)==0){ /*SIGSEGV WHILE COMPARING THE FIRST ELEMENT of the list!!!*/ 
      h->prev->next=h->next; 
      free(h); 
      h=h->prev; 
     } 
    } 
} 

這裏是我的文件,我試圖閱讀

文件。TXT

s201532 加布裏埃萊 除了 1994年5月3日 s225632 馬修 turchetti 31/08/1994 s569874 棕色 pinci 1994年5月9日 s564812 週日 除了 09/02/1981 s114455 Giovannina鱈魚 1950年4月5日s379152白 彈出 26/04/1996 s478125 同性戀 Ravazzolo 28/03/1996 s598741 弗朗西斯 martoscia 24/06/1975 s700265 giuseppina 除了 24/06/1977 s112598 埃內斯托 giliberto 25/12/1920

+2

*最小*例子? *一個*文件,沒有*不相干的事情...... – 2014-12-02 10:22:25

+1

用調試器中運行。如果你不知道如何使用調試器,是時候開始學習它。 – 2014-12-02 10:32:49

回答

0
在eliminia方法,你先遊離H

,然後嘗試訪問它。 你應該做這樣的事情:

LISTA temp; 
... 
... 
temp = h->prev; 
free(h); 
h = temp; 
+0

謝謝你的忠告 – 2014-12-02 10:48:25

0

這是從libc中的STRCMP,我知道如果你給一個NULL指針到strcmp它段錯誤!

int 
strcmp (const char *p1, const char *p2) 
{ 
    const unsigned char *s1 = (const unsigned char *) p1; 
    const unsigned char *s2 = (const unsigned char *) p2; 
    unsigned char c1, c2; 

    do 
    { 
     c1 = (unsigned char) *s1++; 
     c2 = (unsigned char) *s2++; 
     if (c1 == '\0') 
    return c1 - c2; 
    } 
    while (c1 == c2); 

    return c1 - c2; 
} 

它在段錯誤 「的strcmp(H->抄本,代碼)」,如果H->法典== NULL或如果代碼== NULL

+0

Charlon你是對的,但我不明白爲什麼我的頭都空指針,這裏是我的錯在分配? – 2014-12-02 10:47:18

+0

我真的不知道,但事情我知道你需要使用GDB(或LLDB)調試這類問題,這將提高你的調試技巧了。掌握這種類型的調試器的後段錯誤將成爲樂趣:) – Charlon 2014-12-03 14:16:49