05 空指针、野指针与悬空指针

一、三类指针

类型含义注意
空指针 NULL不指向任何对象或函数不能解引用,free(NULL) 安全
野指针非正式术语,常指未初始化或无效指针不能直接读取或写入其指向的内容
悬空指针原目标对象生命周期已结束不能继续访问原对象
int a = 10;
int *p = &a;   // 有效指针
int *q = NULL; // 空指针
int *r;       // 未初始化,不能直接 *r

二、malloc 与 free

#include <stdlib.h>

int *p = malloc(sizeof *p);
if (p != NULL) {
    *p = 10;
    free(p);
    p = NULL;
}
  • malloc 分配动态内存,使用前检查是否返回 NULL。
  • free(p) 释放对象;p = NULL 只是清空指针,不会释放内存。
  • free(NULL) 合法;对同一块已释放内存再次 free 属于未定义行为。
  • 释放后继续访问是 Use After Free;分配后丢失释放途径是 Memory Leak。
  • 多个指针指向同一块内存时,free(p); p = NULL; 不会自动清空其他指针。

三、数组尾后指针

int arr[3] = {10, 20, 30};
int *end = arr + 3;  // 允许形成尾后指针
// *end;              // 未定义行为

数组允许形成 arr 到 arr + 3 的指针,但只有前三个元素可以解引用;arr - 1、arr + 4 等越界指针运算本身也不合法。

记忆要点

指针不为 NULL ≠ 指针有效;释放内存 ≠ 清空所有指针;能形成指针 ≠ 能解引用。