C语言中野指针和悬空指针都是指向无效内存区域的指针,但它们的成因和危害不同。今天我们一起了解一下这两者的区别以及避免方法:
int *p; // 未初始化的指针,此时 p 是野指针
*p = ; // 访问随机地址,可能导致程序崩溃或数据损坏
// 或者指针越界访问
int arr[];
int *p = arr;
for (int i = ; i < ; i++) {
*p++ = i; // 超出数组范围后,p 成为野指针
}
NULL
或有效地址。int *p = NULL; // 初始化为空指针
int a = ;
p = &a; // 指向有效地址
NULL
。int *p = malloc(sizeof(int));
free(p);
p = NULL; // 避免成为野指针
NULL
。if (p != NULL) {
// 安全访问
}
free
或 delete
),但指针本身的值未被修改,仍然保留着原来的地址。int *p = malloc(sizeof(int));
*p = ;
free(p); // 内存释放,但 p 仍指向原地址
*p = ; // 访问已释放的内存,行为未定义
NULL
。free(p);
p = NULL; // 避免悬空指针
int *dangerous_func()
{
int a = ;
return &a; // 返回栈内存地址,调用后成为悬空指针
}
特性 | 野指针 | 悬空指针 |
---|---|---|
成因 | 未初始化、越界、未置空 | 内存释放后未置空 |
指向地址 | 随机(可能从未有效过) | 曾经有效,但已被释放 |
危害 | 更严重(可能指向任意内存) | 严重(访问已释放的内存) |
典型场景 | 未初始化的指针、数组越界 | 动态内存释放后未置空 |
NULL
或有效地址。NULL
。valgrind
检测内存问题,或静态代码分析工具。通过良好的编程习惯和严格的代码检查,可以大幅减少野指针和悬空指针带来的风险。