2014-12-02 120 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