2017-09-20 22 views
3

私はリンクリストの配列を作成する必要があります(写真のように)、これは私がこれまでに作ってきたものである:Cのリンクされたリストの配列:初期化と挿入?

enter image description here

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

int main(void) { 
    Node* link[5]; 
    for(int q = 0; q < 5; q++) { 
     link[q] = malloc(sizeof(struct Node)); 
     link[q] = NULL; 
    } 
} 

を私はCにリンクされたリストを使用していたので、それはしばらくしていますだから、私は多くの構文を忘れてしまい、リンクされたリストをコーディングするときに何が起こるのかを視覚化するのが難しいです。私が誤解していないなら、私のコードでmallocを呼び出すと、まだ何も入っていないNodeを作成していますか?

NULLを指すように初期化します。そして、私はこれをしました

link[q] = NULL; 

私は右のこれはメモリ内でどのように見えるのですか?

| 1 | - > NULL

2 | - > NULL

| 3 | - > NULL


次の問題は、データをリンクリストに挿入することです。

(写真を参照):私が言う配列の3番目のインデックスに別の要素を挿入する場合([3] - > D - > NULL)

これは正しいでしょうか?

Node* newNode = link[3]; 
newNode->data = 1; 
link[3] = newNode; 

ありがとうございます!

+0

挿入が無効です。再びメモリリークが発生します。私の答えを見てください。 –

+0

ありがとう!できるだけ早く編集します:) – Katrina

+0

なぜメモリリークが発生するのですか? – Katrina

答えて

2

このループメモリリークで

Node* link[5]; 
for(int q = 0; q < 5; q++) { 
    link[q] = malloc(sizeof(struct Node)); 
    link[q] = NULL; 
} 

結果最初のメモリに割り当てられ、その後、ポインタがNULLで上書きされるからです。したがって、割り当てられたメモリのアドレスは失われます。あなたはちょうどここ

Node* link[5] = { 0 }; 

を書くことができ

は、ノードがリストの配列の要素に追加することができる方法を示して実証プログラムです。データメンバdataのインセットint可視性のためにcharデータメンバdataを使用しています。

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

typedef struct Node 
{ 
    char data; 
    struct Node *next; 
} Node; 


int push_front(Node **head, char data) 
{ 
    Node *new_node = malloc(sizeof(Node)); 
    int success = new_node != NULL; 

    if (success) 
    { 
     new_node->data = data; 
     new_node->next = *head; 
     *head = new_node; 
    } 

    return success; 
} 

void output(Node **head) 
{ 
    for(Node *current =*head; current != NULL; current = current->next) 
    { 
     printf("%c ", current->data); 
    } 
    printf("%s", "NULL"); 
} 

void display(Node **set, size_t n) 
{ 
    for (size_t i = 0; i < n; i++) 
    { 
     output(set++); 
     putchar('\n'); 
    } 
} 

#define N 5 

int main(void) 
{ 
    Node * link[N] = { 0 }; 

    push_front(&link[0], 'b'); 
    push_front(&link[0], 'a'); 
    push_front(&link[1], 'c'); 
    push_front(&link[2], 'd'); 

    display(link, sizeof(link)/sizeof(*link)); 

    return 0; 
} 

プログラムの出力は

a b NULL 
c NULL 
d NULL 
NULL 
NULL 
+0

あなたの関数push_frontでは、なぜこれをしますか? [int success = new_node!= NULL; ] new_nodeがNULLを指し示す場合がありますか(それにはスペースを割り当てただけですか?特に関数の目的はとにかくそれを収集していますか?)。なぜ成功の価値を返すのでしょうか?戻り値は必要ですか?関数を "void"と宣言するだけで同じではないでしょうか? – Katrina

+0

@Katrina関数mallocは失敗する可能性があります。ノードがリストに正常に追加されたかどうかを判断する方法が必要です。 –

+0

もう一度ありがとう! :) – Katrina

2

すでにノードへのポインタが5つある配列は、linkです。あなただけのことで何を指すように、それらを設定することができます:あなたは、実際のノードをしたくないので、ここで

for (size_t i = 0; i < sizeof link/sizeof *link; ++i) 
link[i] = NULL; 

は何か新しいストレージを割り当ててはならない、あなただけのノードへのポインタをしたい、あなたはすでにそれを持っています。

コードでは、最初に割り当てられ、malloc()によって返されたポインタをNULLですぐに上書きし、そのメモリを永久に失います。良くない。

ノードを作成する場合は、そのノードを割り当てて適切なリストにリンクする必要があります。

+0

良い点!洞察に感謝します。つまり、私のコードを挿入する必要がありますようにする必要があります... Node * newNode = malloc(sizeof(struct Node))? – Katrina

3

は、私の知る限り、あなたのプログラムを理解できるように、次の文は必要ありません。

リンク[Q] = malloc関数(はsizeof(構造体のノード));

NULLポインタから始める必要があるので、リンク[q] = NULL;ちょうどいいです。リスト内の項目を挿入するには

それはそのような何かになる必要がありますので、あなたは、各項目のためのメモリを割り当てる必要があります。私はそれをテストしなかったが、それが動作するはず

Node* newNode = malloc(sizeof(struct Node)); 
newNode->data = 1; 
newNode->next = link[3]; 
link[3] = newNode; 

+0

ありがとう!私はあなたの挿入コードを作成し、私はnewNodeのためのスペースを割り当てた後、あなたがリンク[3]がnewNode = link [3] – Katrina

+0

で指していたことを指摘しなければならないと思います。ポインタを[3]にリンクする必要がありますが、その逆もありません。したがって、リンク[3] = newNodeでなければなりません。 – previ

+0

私の間違い。私は実際にnewNode-> next = link [3]を指していました。私はnewNode = link [3]と考えました。とにかくありがとう:) – Katrina

1

まず最初に、何かを確認するための最善のことは、あなたがそれを見ることがわからない場合です - それを印刷することです。 :あなたがstruct Nodeの大きさで、新たなポインタのvoid *を作り、あなたは2つのオプションを持っているLink[i]あなたは変数にNULL保存するとき、あなたは彼を失うここ

link[q] = malloc(sizeof(struct Node)); 
    link[q] = NULL; 

-

第二には、あなたのコードに誤りがあります

  1. リンクを割り当て、その後、例えばdefualt fieldsでそれを初期化するには - data =-1
  2. 割り当てるいけないとあなたの前にevertyノードでNULLを置きます初期化する

私の助言は、新しいノードの割り当てを追加する必要があるときだけ、2と一緒に行ってください。

関連する問題