2016-10-29 6 views
2

この非常に単純な関数をCで書いて、ノードを単独のリンクリストに追加しました。ここに私の機能があります。 headは、リンクされたリストの最初のノードへのポインタです。リンクリストが空の場合はNULLとなります。 dataが追加される新しいノードのデータフィールドに配置する番号です:頭の単一リンクリストにヘッドノードを追加すると、セグメンテーションフォールトエラーが発生する

Node* InsertAtHead(Node *head, int data) 
{ 
    Node newHeadNode; 
    newHeadNode.data = data; 
    newHeadNode.next = NULL; 

    if (head == NULL) 
    { 
     head = &newHeadNode; 
    } 
    else 
    { 
     newHeadNode.next = head; 
     head = &newHeadNode; 
    } 

    return head; 
} 

定義は以下の通りです:

struct Node 
{ 
    int data; 
    struct Node *next; 
}; 

これは私のマシンではなく、私の同僚のマシン上で動作します。他のマシンでは、プログラムはセグメンテーションフォールトエラーを発生させます。私の機能に何が間違っていますか?

+0

あなたは 'newHeadNode'にスペースを割り当てる必要はないと思いますか? – SMA

+0

@SMAはそれ自体では起こりませんか? – RBT

+1

オハイオ州!私はそれが私にいくつかの手掛かり@ user3121023を与えると思う。 'newHeadNode'は関数にローカルなのでスタックに割り当てられますが、関数スコープがなくなると失われます。 – RBT

答えて

1

あなたの機能を自動保存(スタックの別名newHeadNodeとローカル変数のアドレスを返します。残りのプログラムでこれを使用すると、未定義の動作が呼び出されます。代わりにmalloc()でノードを割り当て、割り当てられたオブジェクトへのポインタを返す必要があります:

#include <stdlib.h> 

Node *InsertAtHead(Node *head, int data) { 
    Node *node = malloc(sizeof(*node)); 
    if (node != NULL) { 
     node->data = data; 
     node->next = head; 
    } 
    return node; 
} 

は、それがNULLでない限り、リストのヒープポインタに戻り値を格納することを忘れないでください。

Node *InsertAtHead(Node **head, int data) { 
    Node *node = malloc(sizeof(*node)); 
    if (node != NULL) { 
     node->data = data; 
     node->next = *head; 
     *head = node; // update the head pointer 
    } 
    return node; 
} 

このAPIでは、割り当てが成功した場合にのみ更新されるヘッドポインタのアドレスを渡します。

+0

最初のコードスニペットの最初の行にコンパイルエラーがほとんど発生していません。私はそれを 'Node * node =(Node *)malloc(sizeof(Node));に変更しました。 'にしてください。 – RBT

+1

コンパイラはC++コンパイラとして構成されている可能性があります。キャストは必要ではなく、Cでは非生産的と見なされます。あなたは ''を含めますか? – chqrlie

+0

しかし、Visual StudioのCプログラムを書くためには、私が信じる特別な方法はありません。私は単に新しいC++コンソールプロジェクトテンプレートウィザードを使用します。 Visual Studioには、Cプロジェクトに固有のプロジェクトテンプレートはありません。私は単にCプログラムを* .cpp拡張子を持つコードファイルに書きます。私が構造体、ポインタなどを使用することに自分自身を制限している限り、それはCプログラムほど良いものです。基本的には、new演算子のようなC++構造体の使用を控えます。 – RBT

0

新しいノードにローカル変数を使用しましたが、関数の終了時に無効になります。 head == NULLの場合に別途条件を設定する必要はありません。

Node* InsertAtHead(Node *head, int data) 
{ 
    Node *newNode = malloc(sizeof *newNode); // note: check the pointer 
    newNode->data = data; 
    newNode->next = head; 
    return newNode; 
} 
関連する問題