此循环将崩溃并在 XCode 4.6.2 中给出 EXC_BAD_ACCESS 的错误
这是循环代码
for (beforeToDel = studentToChange->pFirstClass;
(int)strcmp(beforeToDel->pNext->classId, className) == 0;
beforeToDel = beforeToDel->pNext)
{}
并且不同的变量具有这些值:

非常感谢您提供的任何帮助!
此循环将崩溃并在 XCode 4.6.2 中给出 EXC_BAD_ACCESS 的错误
这是循环代码
for (beforeToDel = studentToChange->pFirstClass;
(int)strcmp(beforeToDel->pNext->classId, className) == 0;
beforeToDel = beforeToDel->pNext)
{}
并且不同的变量具有这些值:

非常感谢您提供的任何帮助!
beforeToDel->pNext->pNext是NULL。您的循环将在第二次迭代时崩溃,试图通过该指针间接比较到className. 您需要在调用之前检查它strcmp。
旁白:为什么要进行类型转换int?
strcmp转换为int. 已经是一个了。beforeToDel是 NULL,或者如果beforeToDel->pNext是 NULL,会发生什么?如果他们没有指向任何东西,那么他们就不能有classIdorpNext成员,对吧?strcmp如果您没有包含,则使用它是错误的<string.h>,因此请确保您已包含它。我假设您正在寻找指向要删除的节点的链接,因此使用了相当尴尬的标识符“beforeToDel”。如果列表的头部是您要删除的节点会发生什么?为什么不从指向studentToChange->pFirstClass链接而不是节点的指针开始并对其进行迭代?这将解决您的头部问题,同时使您的代码更加清晰。
我将像这样声明我的链表:
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)。当找到要删除的节点时,通过 using*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;
}