我在以下链接列表函数中遇到了一个错误,我不知道该怎么做。疯狂的部分(对我而言)是我的代码到目前为止一直运行良好,并且在遇到错误之前仍然可以进行多次调用。
此函数的目标是将新项(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
。再一次,这段代码之前运行良好,所以我无法理解现在发生的事情让它烦恼......
这似乎是重新分配指针变量的问题。不知道出了什么问题。
任何想法,建议,批评。如果需要,我可以附加更多/我的其余代码。真的需要你的帮助,并提前感谢。
答案 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);