C链表无法正确添加数据到列表

时间:2016-07-02 19:13:53

标签: c

有点冗长的问题所以请耐心等待。我正在尝试使用虚拟节点作为头部在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);

希望有所帮助

1 个答案:

答案 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,他们理所当然不喜欢!

我强烈建议在继续尝试编写这样的代码之前,再学习一些指针和动态分配。