2

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

该函数的目标是在 PathItem 链表的末尾添加一个新项(PathItem,其中包含一个 BinaryItem)。我的功能如下

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我在调试器中得到错误。再一次,这段代码以前运行良好,所以我不明白现在发生了什么来扰乱它......

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

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

4

2 回答 2

3

您的主要问题是pathItem作为副本传入,因此对它的更改不会反映在原始代码中。C 使用按值传递的范例(C++ 也使用按值传递,但它至少具有引用类型,因此您不必纠结于 C 的钝指针方法)。

我看不出这是如何工作的,因为如果你传入的指针最初pathItem是 NULL,那么当你返回时它会保持NULL。换句话说,列表总是空的。

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

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

然后,无论您当前pathItem在该函数中的哪个位置,将其替换为(*pPathItem).

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

addPathItemAtEnd (listStart, newItem);

到:

addPathItemAtEnd (&listStart, newItem);

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

于 2012-09-03T04:05:34.920 回答
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);
于 2012-09-03T04:23:01.413 回答