面试题答案
一键面试- 防止悬空指针
- 作用:当使用
free(p)
释放内存后,如果不将p
赋值为NULL
,p
仍然指向原来已释放的内存地址,此时p
就成为了悬空指针。后续如果不小心再次使用p
去访问内存(比如*p = 5;
),会导致未定义行为,程序可能崩溃。而将p
赋值为NULL
,后续再对p
进行解引用操作(如*p
),会立即引发空指针异常,相比未定义行为,这种错误更容易调试和定位。 - 示例:
- 作用:当使用
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int *)malloc(sizeof(int));
if (p!= NULL) {
*p = 10;
printf("Before free: *p = %d\n", *p);
free(p);
// 未将p赋值为NULL
if (*p == 10) { // 此处访问悬空指针,导致未定义行为
printf("This should not happen!\n");
}
}
return 0;
}
- 防止多次释放
- 作用:如果不将
p
赋值为NULL
,在代码的其他地方,程序员可能忘记已经释放过p
所指向的内存,再次调用free(p)
,这会导致双重释放错误,同样会引发未定义行为。将p
赋值为NULL
后,再次调用free(p)
,free
函数对NULL
指针的调用是安全的,不会产生错误。 - 示例:
- 作用:如果不将
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int *)malloc(sizeof(int));
if (p!= NULL) {
*p = 20;
printf("Before first free: *p = %d\n", *p);
free(p);
// 未将p赋值为NULL
free(p); // 双重释放,导致未定义行为
}
return 0;
}
如果将p
赋值为NULL
后,修改代码如下:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int *)malloc(sizeof(int));
if (p!= NULL) {
*p = 20;
printf("Before first free: *p = %d\n", *p);
free(p);
p = NULL;
free(p); // 对NULL指针调用free是安全的
}
return 0;
}
这样在多次调用free(p)
时就不会出现双重释放的未定义行为。