此循环将崩溃,并在XCode 4.6.2中提供EXC_BAD_ACCESS错误
这是循环代码
for (beforeToDel = studentToChange->pFirstClass;
(int)strcmp(beforeToDel->pNext->classId, className) == 0;
beforeToDel = beforeToDel->pNext)
{}
并且不同的变量具有以下值:
非常感谢您提供任何帮助!
答案 0 :(得分:2)
beforeToDel->pNext->pNext
是NULL
。您的循环将在第二次迭代时崩溃,尝试间接通过该指针与className
进行比较。您需要在致电strcmp
之前进行检查。
除此之外:为什么类型转换为int
?
答案 1 :(得分:0)
strcmp
的返回值强制转换为int
。它已经是一个。beforeToDel
为NULL,或者beforeToDel->pNext
为NULL,会发生什么?如果他们指向没有,那么他们就不能拥有classId
或pNext
成员,对吗?如果您未包含strcmp
,则使用<string.h>
会出错,因此请确保包含studentToChange->pFirstClass
。我认为你正在寻找要删除的节点的链接,因此相当笨拙的标识符“beforeToDel”。如果列表的头部是您要删除的节点,会发生什么?为什么不从指向struct list {
struct list *next;
char class_name[];
};
的指针开始并迭代链接而不是节点?这将解决您的头部问题,同时使您的代码更加清晰。
我将按照以下方式声明我的链接列表:
pNext
声明指向link
的任何类型。将其命名为link
,因为此对象将存储指向代码将更新的链接的指针。将其初始化为列表的头部。这样,当第一次迭代导致匹配时,您将轻松地更改列表的头部。在我的功能中,我将回归新的头脑。您不需要在代码中执行此操作。只需确保link = &studentToChange->pFirstClass;
指向列表的头部(例如link
)。
在每次迭代结束时,更新(*link)->next
以指向pNext
(或*link
,在您的情况下)。
在link
上操作,而不是strcmp(*link->classId, class_name) == 0
(例如*link = *link->next;
)。找到要删除的节点后,使用struct list *list_remove_class_name(struct list *head, char *class_name) {
struct list **link = &head;
/* Did you mean != 0 here? */
while (*link != NULL && strcmp(*link->class_name, class_name) == 0) {
*link = *link->next;
}
struct list *node = *link;
if (node != NULL) {
*link = node->next;
}
free(node);
return head;
}
或等效内容在其顶部进行分配。
{{1}}