有点冗长的问题所以请耐心等待。我正在尝试使用虚拟节点作为头部在C中创建双向链表。但是,无论出于何种原因,列表只保存我读入的最后一个节点,并将prev节点指针和下一个节点指针链接到最后一个节点,因此如果我尝试迭代列表,它会陷入无限循环。
这是我的节点头文件和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搞乱了:
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);
}
我已经测试过我的新task_block_type从文本文件中获取正确的数据,并且我使用任务块正确初始化了我创建的新节点。一旦我用add()将它读入我的列表,它就会搞砸了。任何帮助将不胜感激,因为我已经尝试解决这个问题几个小时了,但仍然没有找到解决方案
编辑:
自包含的例子: * node_new意味着是我的节点对象的构造函数,并且应该返回指向节点对象的指针。因此,例如,假设没有包含如上所述的task_block_type的节点,我有一个包含int的节点。如果我想用值5初始化它,我会调用
* newNode =(node_t *)malloc(sizeof(node_t)); * newNode = * node_new(5);
希望有所帮助
答案 0 :(得分:1)
改变这个:
*nodeNew = *node_new(newTask);
对此:
nodeNew = node_new(newTask);
您的原始代码会将node_new()
返回的(取消引用)值复制到<{>>的{em>值(取消引用)*nodeNew
。因此,指针 nodeNew
永远不会使用node_new()
创建的新节点的地址进行更新...因此您将继续覆盖此处的值*nodeNew
将其不变的地址传递给add()
。
而且你的内存泄漏便宜了。您负责free()
malloc()
返回给您的每个指针nodeNew
。但是在这里,出于同样的原因,你没有保留返回指针的副本来启用它......只是一遍又一遍地链接到nodeNew
。
在将指针传递给add()
之前,您需要使用每个新节点的位置更新指针free()
。然后,您实际上将链接不同的节点和原始地址,而不是以泄密的方式将它们复制到同一地址,并将其无限链接到自身。
您还需要 var container = document.querySelector('#ms-container');
var msnry = new Masonry( container, {
itemSelector: '.ms-item',
columnWidth: '.ms-item',
});
在您完成使用后动态分配的所有内存,例如通过在“析构函数”中扫描链表。功能或程序结束时。否则你会泄漏内存。这是一个基本错误,即使在它不能阻止程序工作的情况下,也会浪费用户的注意力。 RAM,他们理所当然不喜欢!
我强烈建议在继续尝试编写这样的代码之前,再学习一些指针和动态分配。