0

私のプログラムが私のメインでセグメンテーション違反を起こす理由を見つけようとしており、決定するのに助けが必要です:

int main (void){
  lista_conti *p = createlist();
  Conto c = malloc(sizeof(Conto));
  c->nome="uno";
  c->predecessore=NULL;
  c->costo=0;
  c->visited=0;
  insert(p,c);
  printf("\n%d\n", isEmpty(p));
  Conto con =p->conto;
  char *nome = con->nome;    /*SEGMENTATION FAULT*/
}

これは、上記のメインを含む私のプログラムの完全なリストです。

/私の構造/

typedef struct lista_conti{

void* conto;
struct lista_conti *succ, *prec;
}lista_conti;


typedef struct{
  char *nome;
  lista_conti *predecessore;   /*valore hash(nome) del predecessore*/
  int costo;
  int visited; /*0 FALSE 1 TRUE*/
}*Conto;

lista_conti *createlist (void){

lista_conti *q = malloc(sizeof(lista_conti));

    if(!q) {
        fprintf(stderr,"Errore di allocazione nella creazione della lista\n");
        exit(-1);
    };
    q->succ = q->prec = q;
    return q;
}

/*Gli passo il puntatore alla testa della lista*/

int isEmpty(lista_conti *p){
  if(p == NULL)
    return 1;
  else
     return 0;
}

/全リストを印刷/

void printList(lista_conti *p){
    lista_conti *r;
     r=p;
     if(r==NULL)
    {
       printf("NO ELEMENT IN THE LIST :");
     return;
     }
   /* traverse the entire linked list */
    while(r!=NULL)
  {   
    Conto cnt = r->conto;     
    printf(" -> %s ",cnt->nome);
    r=r->succ;

  }
   printf("\n");
}

/* head に要素を挿入 */

void insert(lista_conti *p, void* c){ 
   printf("nella funzione insert");
   if(isEmpty(p) == 1){
      printf("\nLISTA VUOTA\n");
      p->conto = c;
      p->succ=NULL;
   }

lista_conti *q = malloc(sizeof(lista_conti));
if(!q) {
    fprintf(stderr,"Errore nell'allocazione del nuovo elemento\n");
    exit(-1);   
};
q->conto = c;
q->succ = p->succ;
p->succ->prec = q;
p->succ = q;
q->prec = p;
}

/* 末尾に要素を挿入します。*/

void insertatend(lista_conti *p, Conto c){

lista_conti *q = malloc(sizeof(lista_conti));

if(!q) {
    fprintf(stderr,"Errore nell'allocazione del nuovo elemento\n");
    exit(-1);   
};
q->conto = c;
q->prec = p->prec;
p->prec->succ = q;
p->prec = q;
q->succ = p;
}




int main (void){
  lista_conti *p = createlist();
  Conto c = malloc(sizeof(Conto));
  c->nome="uno";
  c->predecessore=NULL;
  c->costo=0;
  c->visited=0;
  insert(p,c);
  printf("\n%d\n", isEmpty(p));
  Conto con =p->conto;
  char *nome = con->nome;    /*SEGMENTATION FAULT*/
}

挿入後、con->nome にアクセスしようとすると、プログラムからセグメンテーション フォールトが返されます。どうしてか分かりません。リストを作成するときに問題はありますか? 挿入するときは?

4

2 に答える 2

1

リストの初期化時に、初期化されていないフィールドを持つ最初のノードを作成しますconto

新しいノードを挿入した後、元の最初のノードはそのまま残るため、逆参照しようとp->contoすると、セグメンテーション違反が発生します。

双方向リンク リストを作成する正しい方法は、先頭と末尾を保持する別の構造体を作成することです (必要に応じてカウントを追加することもできます)。どちらも NULL として初期化されています。

挿入すると先頭が更新され、追加すると末尾が更新されます。

于 2012-06-05T14:29:50.160 に答える
1

デバッガを使用する必要があります。GDB と GCC を備えたプラットフォームを使用していると仮定すると、segfault が発生している場所を見つけるために次のことを行う必要があります。

1- -ggdb を使用してコードをコンパイルします。したがって、コンパイル コマンドは gcc -ggdb list.c -o list
2 のようになります。次に、gdb list
3 を実行します。gdb で次のコマンドを入力します。

  • 走る
  • segfault にヒットすると、GDBlistコマンドを使用してソース コードを表示できるはずです。
  • そして、コードが segfault に到達するまでにたどったパスを表示するには、backtrace コマンドを使用できます。

GDB の使用方法を示すこのリンクを参照してください。

`

于 2012-06-05T22:14:48.697 に答える