【问题标题】:segmentation fault when allocating a list from a file从文件分配列表时出现分段错误
【发布时间】:2015-01-30 13:15:10
【问题描述】:

在这个程序中,我将从文件中读取的值插入到列表中。在标题中有句柄

dizionario.h

typedef struct dizionario* DIZ;

lista.h

typedef struct lista* LISTA;

在 main 我调用函数 init_diz 返回一个指针 DIZ

ma​​in.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;
}

当我遍历列表以删除节点时,我使用 sigsegv

ma​​in.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 马泰奥 火锅 1994 年 8 月 31 日 s569874 布鲁诺 平奇 1994 年 5 月 9 日 s564812 多梅尼卡 齐射 1981 年 9 月 2 日 s114455 乔万尼娜 纳塞洛 1950 年 5 月 4 日 s379152 比安卡 流行音乐 1996 年 4 月 26 日 s478125 盖亚 拉瓦佐洛 1996 年 3 月 28 日 s598741 弗朗切斯科 马托夏 1975 年 6 月 24 日 s700265 朱塞皮娜 齐射 1977 年 6 月 24 日 s112598 埃内斯托 吉利贝托 25/12/1920

【问题讨论】:

  • 最小示例? 一个文件,没有无关的东西......
  • 用调试器运行它。如果您不知道如何使用调试器,那么是时候开始学习它了。

标签: c list file memory-management segmentation-fault


【解决方案1】:

在您的 eliminia 方法中,您首先释放 h,然后尝试访问它。 你应该这样做:

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

【讨论】:

  • 感谢您的建议
【解决方案2】:

这是来自 libC 的 strcmp,所以如果你给 strcmp 一个 NULL 指针它是段错误!

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;
}

如果 h->codex == NULL 或 codice == NULL,则在“strcmp(h->codex, codice)”处出现段错误

【讨论】:

  • 你是对的 charlon,但我不明白为什么我在 testa 中有空指针,我的分配错误在哪里?
  • 我真的不知道,但我知道您需要使用 GDB(或 LLDB)来调试此类问题,这也将提高您的调试技能。掌握这种类型的调试器后segfault会变得有趣:)
猜你喜欢
  • 2020-08-14
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
相关资源
最近更新 更多