0

我不是在问效率,进一步列出可访问性或缺少 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;
}

问题是:为什么会抛出

list.exe 中 0x000000013f84107a 处的未处理异常:0xC0000005:访问冲突读取位置 0xffffffffffffffff。

运行时错误以及如何解决?

4

3 回答 3

2

这段代码有很多问题,我认为你最好阅读更多关于指针和参数传递的内容。但是这里有几件事:

  • 当您在函数中声明“列表”时,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
于 2013-01-08T06:38:46.500 回答
0

这段代码需要做很多工作。但是,由于这一行,您会遇到异常:

if(!list->nast) goto exception;

malloc不会将其分配的内存归零。您分配了一个新的列表结构,但由于它没有清零,它的nast指针包含垃圾。上面的检查失败了,在下一行你取消引用这个垃圾并得到异常。

但实际上,即使你修复它,这段代码也需要工作。

于 2013-01-08T06:33:18.163 回答
0

因为你 list=list->nast; 让列表为空。

于 2013-01-08T06:33:45.283 回答