2016-07-02 3 views
-4

長い質問のビットですので、私にご負担ください。ダミーノードを頭に使ってCで二重リンクリストを作成しようとしています。しかし、何らかの理由で、リストは最後に読み込まれたノードだけを保存し、前のノードポインタと次のノードポインタをその最後のノードにリンクするので、リストを繰り返してみると、無限に詰まってしまいますループ。Cリンクリストはリストにデータを正しく追加できません

ここに私のノードヘッダーファイルとCファイルがあります。リンクリストの実装は、完全なリンクリストの実装であることを意味し、私は私だけで必要な機能が含まれていません。

node.h:

#ifndef _node_h 
#define _node_h 

#include "task_block.h" 
#include <stdio.h> 

typedef struct node { 
    task_block_type *data; 
    struct node *next; 
    struct node *prev; 
}node_t; 

node_t *node_new(task_block_type *data); 
void add(node_t *new, node_t *head); 
#endif 

node.c:

#include "node.h" 
#include "task_block.h" 
#include <stdlib.h> 

node_t *node_new(task_block_type *data) { 
    node_t *node = NULL; 

    node = malloc(sizeof(node_t)); 
    node->data = data; 
    node->next = NULL; 
    node->prev = NULL; 

    return node; 
} 

void add(node_t *new, node_t *head) { 
    node_t *current = head; 

    if (head->next == NULL) { 
    head->next = new; 
    head->next->prev = head; 
    return; 
    } 

    while(current->next != NULL) { 
    current = current->next; 
    } 

    current->next = new; 
    current->next->prev = current; 

    return; 
} 

そして最後に、main.cのからめちゃくちゃにされたコード:私はすでに私の新しいtask_bloことをテストしている

while (j < numTasks) { 
     if (tasks[j].taskID == currentID) { 
    *newTask = *task_block_new(tasks[j].taskID, tasks[j].period); 
    newTask->startTime = starts[i]; 
    newTask->deadline = deadlines[i]; 
    newTask->executionTime = executions[i]; 
    *nodeNew = *node_new(newTask); 
    add(nodeNew, eventQueue); 
     } 

ck_typeはテキストファイルから正しいデータを取得し、作成した新しいノードはタスクブロックで正しく初期化されます。しかし、私がadd()を使ってそれを私のリストに読み込むと、それはうんざりします。

自己完結型の例: * node_newがあることを意味する、私は数時間のために、この問題を解決しようとしてきたとしていただければ幸いですすべてのヘルプは今、まだ解決

EDIT発見していませんノードオブジェクトのコンストラクタであり、ノードオブジェクトへのポインタを返すことになっています。たとえば、上記のようにtask_block_typeを含むノードを持つ代わりに、intを含むノードがあります。値を5に初期化する場合は、

* newNode =(node_t *)malloc(sizeof(node_t));を呼び出します。 * newNode = * node_new(5);

+0

SSCCEを表示してください。 – 2501

+0

@EdHealは彼のコンパイラに依存します –

+3

これはCで、 'new'は有効な変数名です。 – 2501

答えて

1

変更この役立ちます希望:これに

*nodeNew = *node_new(newTask); 

nodeNew = node_new(newTask); 

あなたのオリジナルのコードをコピー(間接参照)node_new()によって返さを(参照の)*nodeNewで。したがって、ポインタnodeNewnode_new()によって作成された新しいノードのアドレスで更新されることは決してありません...あなたはadd()への不変のアドレスを渡しながら*nodeNewで値を上書きしておきます。

およびあなたは、お買い得にメモリリークを取得します。あなたはmalloc()によって返されたすべてのポインタをfree()する責任があります。しかし、ここでは、上記の理由と同じ理由で、これを可能にする返されたポインタのコピーを保持していません...ちょうどnodeNewに何度もリンクしています。

add()に渡す前に、ポインタnodeNewを新しいノードの位置で更新する必要があります。そして実際にはの異なるノードをリンクしていて、それらの元のアドレスで、同じアドレスに漏れた形でそれらをコピーし、それ自体を無限にリンクするのではなく、

また、使用を終了した後に動的に割り当てたすべてのメモリは、free()にする必要があります。リンク先リストを「デストラクタ」機能で掃除するか、プログラムの最後で削除します。それ以外の場合は、メモリがリークしています。これは基本的なエラーであり、プログラムの動作を停止させない場合でも、ユーザーのRAMを無駄にします。

このようなコードを書くのを続ける前に、ポインタと動的割り当てをもっと検討することを強くお勧めします。

+0

助けてくれてありがとうございます。もともと、task_blockの配列の値を同様の方法で初期化するので(task [i] = * some_function())、うまくいきましたので、これは問題ではないと思いました。私は明らかに必要なように、もう一度、ポインタをもう一度見直します。再び、助けをありがとう – Nick

+0

@ニック私に知らせてくれてありがとう。 SOの答えがあなたに役立つときはいつでも、upvoteし、受け入れられたものとして最高のものをマークしてください!あなたの 'task []'割り当てに関しては、うまくいくかもしれませんが、 'some_function()'が 'node_new()'のようなものであれば、メモリも漏れてしまいます。私はそれを確認することをお勧めします。 –

関連する問題