MST

星途 面试题库

面试题:C语言中NULL指针与内存管理

考虑一个动态内存分配的场景,你使用`malloc`分配了一块内存并将其地址赋给一个指针`int *p = (int *)malloc(sizeof(int))`。之后你释放了这块内存`free(p)`,然后将`p`赋值为`NULL`。阐述将`p`赋值为`NULL`在后续代码中的重要性,特别是在防止悬空指针和多次释放方面的作用,并举例说明如果不将`p`赋值为`NULL`可能导致的问题。
20.4万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
  1. 防止悬空指针
    • 作用:当使用free(p)释放内存后,如果不将p赋值为NULLp仍然指向原来已释放的内存地址,此时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;
}
  1. 防止多次释放
    • 作用:如果不将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)时就不会出现双重释放的未定义行为。