2017-11-03 17 views
-3

問題の解決に問題があります。私はこのコードを試しながら、セグメンテーションフォールト:11エラーを続行します。私がコードを変更するたびに、エラーがポップアップし、どこに欠陥があるかわからないので、誰かが欠陥を見たら私はすばらしいだろう。セグメンテーションフォールト11:10

事前におねがいします。

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include "dbg.h" 

typedef struct node{ 
    char *data; 
    struct node *next; 
} node_t; 

node_t **push(node_t **head, char *data){ 
    node_t *new_node; 
    new_node = malloc(sizeof(node_t)); 

    new_node->data = data; 
    new_node->next = *head; 
    *head = new_node; 
    free(new_node); 

    return head; 
} 

int main(int argc, char *argv[]) 
{ 
    node_t **head; 
    char *data = "hoi"; 
    char *data2 = "hallo"; 
    head = malloc(20 * sizeof(node_t)); 
    head = push(head, data); 
    head = push(head, data2); 
    printf("%s\n",(*head)[1].data); 
    free(head); 

    return 0; 
} 
+1

segfaultが原因であることを理解していますか?これは1日に10回尋ねられ、答えはほぼ同じです。 – Carcigenicate

+1

あなたはこれを読むのが好きかもしれません:[小さなプログラムをデバッグする方法](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – alk

+2

'head = malloc(20 * sizeof (node_t)); '見た目が正しくない!! –

答えて

1

傷:

  • あなたpush()機能はpush()の呼び出しにそれがアクセスしやすく、*headnew_nodeの値を代入していますが、自由new_node機能の終了時に、それダングリング作りポインタ。それはセグメンテーションの誤りの良い根拠です。
  • headはポインタへのポインタですが、malloc()呼び出しの結果が割り当てられており、そのポインタはノードへのポインタである必要があると思われます。
  • デザインが混乱しています:push()またはのメモリをmain()に割り当てますか?確かに、両方は良い選択ではありません。
  • 定数ではない定数のポインターを指しています。これは危険です。これらのポインタを介して定数文字列に書き込むと、セグメント化エラーにもつながる可能性があります。ここで

働くあなたのプログラムのバージョンである:私は別名、LIFO構造を実現し

#include <stdio.h> 
#include <stdlib.h> 

struct node { 
    const char *data; 
    struct node *next; 
}; 

static struct node *push(struct node *head, const char *data) { 
    struct node *node; 
    node = malloc(sizeof *node); 

    node->data = data; 
    node->next = head; 

    return node; 
} 

int main(int argc, char *argv[]) 
{ 
    struct node *head = NULL; 
    const char *data = "hoi"; 
    const char *data2 = "hallo"; 
    head = push(head, data); 
    head = push(head, data2); 
    struct node *node = head; 
    while (node) { 
     printf("%s\n", node->data); 
     node = node->next; 
    } 

    return 0; 
} 

注意を。 push()関数は通常、スタックに適用されるため、スタックと呼びます。

論理的な次のステップは、pop()関数を実装することです。通常は、pop()がノードを解放してデータを返すことをお勧めします。それはあなたのAPIにとって素晴らしい対称性を提供します。

+0

いつnew_nodeを解放する必要がありますか?解放しないとメモリが失われるためです。 –

+0

@ John-Johnあなたがもう必要がなくなったらそれを解放します。あなたがそれをもはや必要としない時を決めるまでに。 –

+1

@JohnJohnあなたがそれを済ませたら、それを解放する必要があります。それは、リンクされたリスト全体がもう必要でなくなったからです。あなたがここでやることは、アイスクリームを買い、それを投げ捨て、そしてそれを食べようとするようなものです。 –

関連する問題