之前写程序的时候报出段错误:segmentation fault就写了一边关于段错误的介绍。详细介绍在http://t.csdnimg.cn/6y56l。但是说到底段错误不过是野指针的成因之一。这篇主要讲解野指针的产生和解决方法。
int main()
{
int* p;
*p = 10;
return 0;
}
int* p局部变量指针未初始化,默认为随机值;这个变量不初始化,代表随机值,我们不知道它里面是什么?有没有被使用?能不能用?我们把这种使用内存单元的情况叫不合法使用内存。
而当我们*p = 10;这样去使用一个不合法的内存,就会造成野指针;
解决方法也很简单:对指针进行初始化;具体方法有下面几种:
int main()
{
int a = 10;
int b = 4;
int* p = &a;//直接初始化;
*p = 3;
int* q = NULL;//当我们不确定给这个给指针赋什么值就可以给他赋值NULL
//表示为空,当我们需要时重新初始化;
int* q = &b;
return 0;
}
第二种:2.越界访问
同样我们看一个代码:
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i <= 10; i++)
{
*p = i;
p++;
}
return 0;
}
我们定义一个数组,然后通过指针来把数组里面的元素改变为1,2,3.......9.但是实际上数组只有10元素。从0开始到9,当指针指向的范围超出数组arr的范围时,p就是野指针也就是超出边界。这就要我们注意内存单元的边界;
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 未知 |
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i <10; i++)
{
*(p++) = i;
printf("%d ", arr[i]);
}
return 0;
}
看以下效果:
第三种:指针指向的地址被释放;
这种往往在我们构建函数的过程当中会出现这中问题;简单举个栗子:
int* test()
{
int a = 10;
int* q = &a;
return q;
}
int main()
{
int* p = test();
return 0;
}
我们简单创建一个函数返回这个函数里面变量a的地址q给p看似是不是没有问题?
但是这个函数里面的a时局部变量,当函数进行到这的时候,a被创建,当执行完以后就会被销毁(释放)从而不存在或者说,a的地址不在属于a。我们的指针p接收的就会时一个随机值,不确定的地址,从而导致野指针的产生。
所以要求我们在使用指针的时候要检测指针的合法性!
当然我们也可以结合static和const的使用,延长生命周期或者演变为常量,或者使用全局变量来改变这种情况。
简单写一下:
int* test()
{
const int a = 10;
int* q = &a;
return q;
}
int main()
{
int* p = test();
printf("%d", *p);
return 0;
}
这样就可以运行
下面是对于使用指针的注意地方的总结:
1.指针初始化;
2.小心指针越界;
3.指针指向空间是否被释放;
4.避免使用返回局部变量的地址;
5.指针使用前检查有效性
总的来说野指针的问题还是集中一句话,内存不合法使用所导致产生。
需要代码的可以到我gitee上找:链接:https://gitee.com/luochen-su-yu/causes-and-solutions.git