无法将元素添加到单向简单列表

标签 c list

如果这个程序的关键错误自由流程不需要的话,我不是在问效率、进一步的列表可访问性或缺少 free() 函数:

#include <stdlib.h>


typedef struct a
{
    a * nast;
    double v;

};

void add(struct a* list,double d)
{
    list = (a*)malloc(sizeof(a));

    if(!list->nast) goto exception;

    list=list->nast;

    list->v=d;

    return;

exception:
    printf("Cannot add to the list \n");
}


int main()
{
    struct a l;

    add(&l,-602.1);

    return 0;
}

问题是:为什么会抛出

Unhandled exception at 0x000000013f84107a in list.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.

运行时错误以及如何修复它?

最佳答案

这段代码有很多问题,我认为你最好阅读更多关于指针和参数传递的内容。不过,这里有一些事情:

  • 当您在 main 函数中声明“列表”时,它已经在堆栈上分配了。然后,您尝试在 add 函数中重新分配它。

  • 如果要在add函数中分配节点,则需要通过引用传递一个指针,即指向指针的指针。这是因为否则指针将按值传递,并且当函数返回时,对其所做的所有更改(即实际指针,而不是它指向的内容)都将丢失。

  • malloc 函数不会清除分配的内存。如果您希望自动发生,您应该使用 calloc 函数。

  • 您不需要将节点链接到列表中,只需使用(未初始化的)nast 指针覆盖列表头即可。

  • 您在结构中使用了 typedef,但实际上并未为此 typedef 定义名称。

  • 请,哦,请不要使用goto!如果使用得太多,它会让你的代码很难阅读和遵循(而且使用太多,很多人会认为即使使用一次就太多了)。

<小时/>

如果我这样做,我会让我的 add 函数将对指针的引用作为参数,以及要添加到列表中的值。然后,我会为该值分配一个新节点,并通过使 next 指针指向旧列表来将其链接到列表中,然后重新分配列表指针以指向新节点。如果传递的列表为NULL,则只需使列表指向新节点即可。

类似这样的事情:

struct node
{
    struct node *next;
    double       value;
};

void add(struct node **l, const double value)
{
    /* Allocate a new node, use `calloc` to clear the memory automatically */
    struct node *n = calloc(1, sizeof(struct node));

    /* Set the value of the new node */
    n->value = value;

    /* Is the list non-null? */
    if (*l != NULL)
    {
        /* Yes, make the `next` pointer point to the old list */
        n->next = *l;
    }

    /* Make the list point to the new node */
    *l = n;
}

这个函数可以这样调用:

 /* Initialize to `NULL` to mark the list as empty */
struct node *list = NULL;

/* Add two nodes, passing the list pointer by reference */
add(&list, 12.34);
add(&list, 56.78);

列表现在有两个节点:

  1. 列表中的第一个节点包含值 56.78
  2. 列表中的第二个节点包含值12.34

关于无法将元素添加到单向简单列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14209376/

相关文章:

c - 程序输出说明

c - C的打开覆盖文件将被打开,并且fdopen返回NULL

c - 以所需的方式对数组进行排序

c - 打印列表时省略最后一个逗号

list - jaxb 使用对象列表解码对象返回包含一个元素且所有属性为 null 的列表

c# - 以字符串列表作为值的字典

c - 静态分支预测/GCC 优化

c - C 中评估后递增变量

python - arr.append(curr) 和 arr.append(curr[ :])

c# - List索引和Array索引的区别