野指针:程序崩溃的隐形杀手
目录
一、概念
二、野指针的成因
1、指针未初始化
2、指针越界访问
3、指针指向已释放的内存
三、如何规避野指针
1、指针初始化
2、防止指针越界
3、指针使用后及时置NULL
4、避免返回局部变量地址
四、总结
一、概念
野指针(Dangling Pointer)是指指针变量指向的内存位置是不可知、随机或无效的。这种指针不指向任何合法的内存空间,使用野指针可能导致程序崩溃或不可预测的行为。
二、野指针的成因
1、指针未初始化
在C语言中,局部指针变量如果不初始化,其值是随机的(垃圾值),直接解引用会导致未定义行为。
#include <stdio.h>
int main()
{ int *p; // 局部指针变量未初始化,值为随机内存地址*p = 20; // 解引用野指针,可能导致程序崩溃return 0;
}
2、指针越界访问
当指针访问超出其分配的内存范围时,就会变成野指针。
#include <stdio.h>
int main()
{int arr[10] = {0};int *p = &arr[0];for(int i = 0; i <= 11; i++) // 故意越界访问{*(p++) = i; // 当i>9时,p成为野指针}return 0;
}
3、指针指向已释放的内存
当指针指向的内存被释放后,如果没有置空,指针就会变成野指针。现在可以先理解为局部变量被释放了,但是却要返回这个变量。后面学到动态内存管理就会明白。。。。。。
#include <stdio.h>
#include <stdlib.h>int* create_int()
{int *p = (int*)malloc(sizeof(int));*p = 100;free(p); // 内存释放后,p成为野指针return p; // 返回野指针
}int main()
{int *p = create_int();printf("%d\n", *p); // 解引用野指针,未定义行为return 0;
}
三、如何规避野指针
1、指针初始化
-
明确知道指针指向时,直接赋地址值
-
不确定指针指向时,初始化为NULL
#ifdef __cplusplus#define NULL 0 #else#define NULL ((void *)0) #endif
-
NULL是C语言中定义的一个标识符常量,其值为0。由于0在指针上下文中被视为无效地址,因此对该地址进行读写操作会导致报错。
#include <stdio.h>
int main()
{int num = 10;int *p1 = # // 明确指向int *p2 = NULL; // 不确定指向时初始化为NULL// 使用前检查if(p1 != NULL) {printf("%d\n", *p1);}return 0;
}
2、防止指针越界
确保指针只在合法范围内使用,特别是数组操作时注意边界检查。
3、指针使用后及时置NULL
当指针变量指向某块内存区域时,我们可以通过该指针访问该区域。当不再需要使用该指针访问内存时,应将其置为NULL。按照编程惯例,NULL指针不应被访问,同时在使用指针前应当检查其是否为NULL。
我们可以将野指针比作流浪狗——放任不管的流浪狗相当危险。就像给流浪狗系上绳子能降低风险一样,及时将指针赋值为NULL就相当于把野指针"拴住",从而对其进行有效管理。
但需注意的是,即使被拴住的狗也应保持距离,不可随意挑逗。同理,在使用指针前,我们必须检查其是否为NULL(即是否为"被拴住的流浪狗")。若指针为NULL则不能直接使用,只有在确认非NULL的情况下才能安全使用。
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];for(int i=0; i<10; i++) {*(p++) = i;}// 使用完毕后置NULLp = NULL;// 再次使用前重新赋值并检查p = &arr[0];if(p != NULL) {// 安全操作}return 0;
}
4、避免返回局部变量地址
函数返回后,其栈帧被销毁,局部变量的地址不再有效。
// 错误示例
int* get_local_pointer()
{int local = 100;return &local; // 返回局部变量地址
}// 正确做法:返回动态分配的内存或静态变量地址
int* get_valid_pointer()
{static int persistent = 100; // 静态变量return &persistent;// 或者// int *p = malloc(sizeof(int));// *p = 100;// return p;
}
四、总结
野指针是C/C++程序中常见的安全隐患,通过良好的编程习惯可以有效避免:
-
始终初始化指针
-
注意指针操作的范围
-
及时置空不再使用的指针
-
谨慎处理指针的返回和传递
养成这些习惯可以大大减少由野指针引起的内存错误和程序崩溃。