void add(queue currentQueue, int data){
構造体のコピーを に渡しているため、コピーのメンバーのみが変更されます。それ自体のメンバーを変更できるようにするには、関数にa を渡す必要があります。queue
add
queue*
queue
void add(queue *currentQueue, int data){
if (currentQueue == NULL) {
exit(EXIT_FAILURE);
}
addTail(currentQueue->list, data, data+5);
currentQueue->back = currentQueue->back->next;
}
そしてそれを次のように呼び出しますadd(&your_queue);
あなたのaddTail
関数では、あまりにもあるかどうかを確認する必要head
がありNULL
ます。
そして
node *newNode = (struct listNode *)malloc(sizeof(node));
newNode = initNode(value, length);
でaddTail
、深刻な問題を抱えています。代入newNode = initNode(value, length);
を使用すると、ちょうどmalloc
ed メモリへの参照が失われます。
initNode
malloc
新しいメモリ チャンクが「単なる」メモリ リークである場合は、 in を削除する必要がありmalloc
ますaddTail
。
そうしないinitNode
と、ローカル変数のアドレスが返されるのではないかと心配しています。
node * initNode(int val, int len) {
node new;
new.nodeValue = val;
new.nodeLength = len;
new.next = NULL;
return &new;
}
これinitNode
に似ていると、関数が戻るとすぐにアドレスが無効になるため、問題が発生します。initNode
しかし、そのように見えた場合、コンパイラは警告するはずです。
とにかく、 のコードを見initNode
ないと、原因を診断できません。
しかし、あなたがに変更addTail
した場合
void addTail (node *head, int value, int length) {
if (head == NULL) { // violation of contract, die loud
exit(EXIT_FAILURE);
}
node *current = head;
node *newNode = malloc(sizeof(node));
if (newNode == NULL) {
exit(EXIT_FAILURE); // or handle gracefully if possible
}
newNode->nodeValue = value;
newNode->nodeLength = length;
newNode->next = NULL;
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
それはうまくいくはずです。
back
ただし、リストの最初と最後のノードへのポインターがあるため、ポインターを使用して新しいノードを追加する方が効率的です。
void add(queue *currentQueue, int data){
node *newNode = malloc(sizeof *newNode);
if (newNode == NULL) {
exit(EXIT_FAILURE); // or handle gracefully if possible
}
newNode->nodeValue = data;
newNode->nodeLength = data+5;
newNode->next = NULL;
currentQueue->back->next = newNode;
currentQueue->back = newNode;
}
最後を見つけるためにリスト全体をトラバースする必要がないためです。
簡単なサンプルプログラム
#include <stdlib.h>
#include <stdio.h>
struct listNode {
int nodeLength;
int nodeValue;
struct listNode *next;
};
typedef struct listNode node;
struct QueueRecord {
node *list;
node *front;
node *back;
int maxLen;
};
typedef struct QueueRecord queue;
node *createList (){
node *head = NULL;
head = (struct listNode *)malloc(sizeof(node));
head->next = NULL;
return head;
}
void addTail (node *head, int value, int length) {
if (head == NULL) { // violation of contract, die loud
exit(EXIT_FAILURE);
}
node *current = head;
node *newNode = malloc(sizeof(node));
if (newNode == NULL) {
exit(EXIT_FAILURE); // or handle gracefully if possible
}
newNode->nodeValue = value;
newNode->nodeLength = length;
newNode->next = NULL;
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
queue createQueue(int maxLen){
queue newQueue;
newQueue.list = createList();
newQueue.front = newQueue.list;
newQueue.back = newQueue.list;
newQueue.maxLen = maxLen;
return newQueue;
}
void add(queue *currentQueue, int data){
if (currentQueue == NULL) {
exit(EXIT_FAILURE);
}
addTail(currentQueue->list, data, data+5);
currentQueue->back = currentQueue->back->next;
}
int main(void) {
queue myQ = createQueue(10);
for(int i = 1; i < 6; ++i) {
add(&myQ, i);
printf("list: %p\nfront: %p\nback: %p\n",
(void*)myQ.list, (void*)myQ.front, (void*)myQ.back);
}
node *curr = myQ.front->next;
while(curr) {
printf("Node %d %d, Back %d %d\n", curr->nodeValue,
curr->nodeLength, myQ.back->nodeValue, myQ.back->nodeLength);
curr = curr->next;
}
while(myQ.list) {
myQ.front = myQ.front->next;
free(myQ.list);
myQ.list = myQ.front;
}
return 0;
}
代替add
実装でも期待どおりに動作します。