目录
10.野指针
*定义
*案例
11.野指针规避方法
*初始化
*防止越界
*指针变量不再使用时,及时置NULL,指针使用之前检查有效性
*避免返回局部变量的地址
*assert断言
12.assert断言
*解释
*作用
*优点
*启用assert的开关
往期推荐
承接上篇 38.【C语言】指针(重难点)(C)
10.野指针
*定义:指针指向的位置是不可知(随机的、没有明确限制的)
*案例
随机的(没有初始化):
int* p;
*p = 10;//非法访问
没有明确限制的(越界访问)
#include <stdio.h>
int main()
{int arr[10] = {0};int* p = &arr[0];for(int i=0; i<=11; i++){ *(p++) = i;//当i>=10时,p就是野指针}return 0;
}
注意:*(p++) = i;先使用,后++ --> *p = i; p++;
*指针指向的空间释放
#include <stdio.h>
int* test()
{int n = 100;return &n;
}int main()
{int* p = test();printf("%d\n", *p);return 0;
}
分析:test函数定义的n的生命周期介于test函数的 { 与 } 之间,一旦出test函数,n交换给操作系统,没有使用权限,即空间释放
11.野指针规避方法
*初始化
明确知道指针指向哪里就直接赋值地址,如果不知道指针应该指向哪里,给指针赋值NULL(空指针)
int num = 10;
int*p1 = #
int*p2 = NULL;
#define NULL ((void *)0) //把0转换为(void *)
内存查看p2的地址
注意:空指针不能访问(*p2=10;不允许)
*防止越界
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int* p = &arr[0];int i = 0;for(i=0; i<10; i++){*(p++) = i;}//p已越界,把p置为NULLp = NULL;return 0;
}
*指针变量不再使用时,及时置NULL,指针使用之前检查有效性
规则:只要是NULL指针就不去访问,同时使用指针之前可以判断指针是否为NULL
if (p2 != NULL)
{dosomething;
}
*避免返回局部变量的地址
见本篇:指针指向的空间释放
*assert断言
13.assert() (assert v.断言)
*解释:assert(表达式); 如果表达式为真(返回值非零),继续执行;如果表达式为假(返回值为零),则报错
*作用:在运行时确保程序符合指定条件,如果不符合,就报错终止运行
使用前引用头文件
#include <assert.h>
*优点:报错是会在窗口显示没有通过的表达式,以及包含这个表达式的文件名和行号
#include <assert.h>
int main()
{int* p = NULL;assert(p != NULL);return 0;
}
*启用assert的开关
禁用assert:在#include <assert.h>前加#define NDEBUG,可以提高程序的运行效率,尽管assert(表达式)为假,但不会报错,继续执行,
启用assert:直接注释掉#define NDEBUG
注:NDEBUG为No Debug
往期推荐:
19.【C语言】指针(重难点)(A)
37.【C语言】指针(重难点)(B)
38.【C语言】指针(重难点)(C)