指针

指针

1. 指针的作用

  • 使程序简洁、紧凑、高效
  • 有效地表示复杂的数据结构
  • 动态分配内存
  • 能直接访问硬件
  • 能够方便的处理字符串
  • 得到多于一个的函数返回值

2. 指针和指针变量


指针初始化

int main() {
    int a = 10;
    int * p = &a;  //  p 是指针变量,p 的内容为 a的地址
    printf("&a=%p p=%p &p=%p\n", &a, p, &p);
    return 0;
}

3. 指针的目标和解引用

指针指向的内存区域中的数据称为指针的目标

如何通过指针修改指针的目标呢?===> 指针的解引用

int main() {
    int a = 10;
    int * p = &a;
    (*p)++;  //  间接地去访问了指针的目标
    cout << a << endl;  //  11
    return 0;
}

关于指针的3种写法:

4. 指针的赋值

0是有效的地址(最小的)

指针的赋值



数组名代表了整个数组的起始地址(也就是a[0]的地址)

int main() {
    int a[] = {1, 2, 3};
    int * p;
    printf("%p %p\n", a, &a[0]);
    return 0;
}

5. 空指针

  • 不同于没有初始化的指针
int * p,  //  没有初始化的指针(这里说的空指针,不是指这个意思)
int * p = &a;
  • 在 C 语言中,NULL 本质是:0
#defne NULL (void *)0  //  在 C 中 NULL 是强制类型转换为 void* 的0

Demo

int main() {
    int a = 10;
    int *p;
    int *q = NULL;
    printf("p=%p q=%p\n", p, q);
    return 0;
}


空指针为什么指向0地址处???2个原因

  1. 指针如果没有给定初始值,值是不确定的
  2. 0地址是一个特殊地址,在一般的操作系统中都是不可访问的,如果C语言不按照规矩(不检查是否等于 NULL 就去解引用)写代码直接去解引用就会触发段错误(Segmentation fault)

6. 野指针(Wild)

定义和成因

定义:

  • 指针指向的位置是不可知的(随机的,不正确的,没有明确指向的)
  • 指向被释放的内存或者没有访问权限的内存的指针(非法访问)

如何造成的:

  1. 野指针的措误来源就是指针定义了以后没有初始化,也没有赋值(总之就是指针没有明确的指向一个可用的内存空间),然后去解引用。
  2. 指针越界访问
int main() {
    int a[] = {1, 2, 3};
    int *p = &a[3];  //  越界
    printf("%p\n", p);
    return 0;
}
  1. 指针指向的空间已经释放了
int main() {
    int m = 10;
    int *p = &m;
    int i;
    for(i = 0; i < 3; i++){
        int t = 0;
        p = &t;
        t++;
        printf("t=%d %p\n", t, p);
    }
    printf("m:%d %p\n", *p, p); //  指针所指向的空间已经被释放了   
    *p = 2000;
    return 0;
}

危害

  • 野指针指向别的变量(指针所指向的那个变量)的地址
  • 即指向了一个地址是不确定的变量,去解引用,结果不可知的。
  1. 段错误
    指向不可访问(操作系统不允许访问的敏感地址,如内核空间)的地址,结果是触发段错误
  2. 程序错误被掩盖
    指向一个可用的、而目没什么特别意义的空间(譬如我们曾经使用过但是已经不用的空间),这时候程序运行不会出错,也不会对当前程序造成损害这种情况下会掩盖你的程序错误,让你以为程序没问题,其实问题是非常严重的
  3. 程序出现离奇错误
    指向了一个可用的空间,而且这个空间其实在程序中正在被使用(譬如说是程序的一个变量x),那么野指针的解引用就会刚好修改这个变量的值,导致这个变量莫名其妙的被改变,程序出现离奇的错误。一般最终都会导致程序崩溃,或者数据被损害

如何避免

posted @ 2024-08-13 01:06  爱新觉罗LQ  阅读(17)  评论(0编辑  收藏  举报