面试题答案
一键面试可能出现的微妙错误
- 空指针解引用:如果多级指针中的任何一级指针为
NULL
,直接解引用该指针会导致空指针解引用错误。例如,ppp_head
本身可能为NULL
,或者*ppp_head
为NULL
,又或者**ppp_head
为NULL
。 - 内存访问越界:当遍历链表时,如果
next
指针指向了非法的内存地址(例如已释放的内存或者超出分配内存的范围),继续解引用next
指针会导致内存访问越界。
确保程序正确性和健壮性的方法
- 逐级检查指针是否为
NULL
:在每次解引用指针之前,都要检查该指针是否为NULL
。对于多级指针,需要从最外层指针开始,逐层检查。 - 检查链表结束:在遍历链表时,每次访问
next
指针前,确保next
指针不为NULL
,以避免访问越界。
代码示例
#include <stdio.h>
#include <stdlib.h>
struct Node {
struct Node *next;
int data;
};
void traverseAndPrint(struct Node ***ppp_head) {
if (ppp_head == NULL) {
return;
}
struct Node **pp_head = *ppp_head;
if (pp_head == NULL) {
return;
}
struct Node *p_head = *pp_head;
if (p_head == NULL) {
return;
}
struct Node *current = p_head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
}
int main() {
// 创建链表
struct Node *node1 = (struct Node *)malloc(sizeof(struct Node));
node1->data = 1;
struct Node *node2 = (struct Node *)malloc(sizeof(struct Node));
node2->data = 2;
node1->next = node2;
node2->next = NULL;
struct Node **pp_head = &node1;
struct Node ***ppp_head = &pp_head;
traverseAndPrint(ppp_head);
// 释放内存
struct Node *temp;
while (node1 != NULL) {
temp = node1;
node1 = node1->next;
free(temp);
}
return 0;
}
在上述代码中,traverseAndPrint
函数通过逐级检查指针是否为 NULL
来避免空指针解引用错误。在遍历链表时,通过检查 current != NULL
来避免内存访问越界。main
函数创建了一个简单的链表,并调用 traverseAndPrint
函数进行遍历和打印,最后释放链表所占用的内存。