C:将新项目分配给链接列表中的“下一个”指针失败

时间:2012-09-03 04:02:52

标签: c list pointers linked-list

我在以下链接列表函数中遇到了一个错误,我不知道该怎么做。疯狂的部分(对我而言)是我的代码到目前为止一直运行良好,并且在遇到错误之前仍然可以进行多次调用。

此函数的目标是将新项(PathItem,其中包含BinaryItem)添加到PathItems链接列表的末尾。我的功能如下

void addPathItemAtEnd(struct PathItem * pathItem, struct BinaryItem * binaryItem) {
    if (pathItem == NULL) {
        pathItem = malloc(sizeof(struct PathItem));
        pathItem->binaryItem = binaryItem;
        pathItem->next = NULL;
    } else {
        while (pathItem->next != NULL) {
            pathItem = pathItem->next;
        }
        struct PathItem * newPathItem = malloc(sizeof(struct PathItem));
        newPathItem->binaryItem = binaryItem;
        newPathItem->next = NULL;
        pathItem->next = newPathItem;        
    }
}

有问题的行为pathItem->next = newPathItem。我在调试器中收到错误EXC_BAD_ACCESS。再一次,这段代码之前运行良好,所以我无法理解现在发生的事情让它烦恼......

这似乎是重新分配指针变量的问题。不知道出了什么问题。

任何想法,建议,批评。如果需要,我可以附加更多/我的其余代码。真的需要你的帮助,并提前感谢。

2 个答案:

答案 0 :(得分:3)

您的主要问题是pathItem作为副本传入,因此对其的更改不会反映在原始代码中。 C使用pass-by-value范例(C ++也使用pass by value但它至少有引用类型,所以你不必使用C的钝指针方法)。

我无法看到这个曾经如何工作只是因为,如果你作为pathItem传入的指针最初是NULL,那么保持 NULL你什么时候回来。换句话说,列表总是空的。

最简单的解决方法是将原型更改为:

void addPathItemAtEnd (struct PathItem *pPathItem, blah blah blah ...

然后,无论您当前在该函数中有pathItem,请将其替换为(*pPathItem)

当然,用指针调用它,改变(类似):

addPathItemAtEnd (listStart, newItem);

为:

addPathItemAtEnd (&listStart, newItem);

另外,健壮的代码也会检查malloc的返回值并采取相应的行动。虽然课堂作业和小型个人项目可以在假设没有失败的情况下逃脱,但这不会在现实世界中削减它: - )

答案 1 :(得分:1)

您按值传递列表的根目录,因此永远不会修改实际的根目录。传入& root,以便可以修改它。

struct PathItem *root = NULL;

void addPathItemAtEnd(struct PathItem **pRoot, struct BinaryItem * binaryItem) {
    // advance pRoot so that either it points to the original root or it
    // points at the next field of the last item
    while (*pRoot)
        pRoot = &(*pRoot)->next;
    // add the new item
    struct PathItem *p = malloc(sizeof(struct PathItem));
    // TODO check p!= NULL
    p->next = NULL;
    p->binaryItem = binaryItem;
    *pRoot = p;
}

被称为

addPathItemAtEnd(&root, blah);