zoukankan      html  css  js  c++  java
  • (C语言内存十九)C语言野指针以及非法内存操作

    野指针

    如果一个指针指向的内存没有访问权限,或者指向一块已经释放掉的内存,那么就无法对该指针进行操作,这样的指针称为野指针(Wild Pointer)。

    指向没有访问权限的内存

    请看下面的代码:

    #include <stdio.h>
    int main(){
        char *str;
        gets(str);
        puts(str);
        return 0;
    }
    

    在GCC下运行,输入一个字符串后会提示段错误(Segment Fault)。在VS下运行,输入一个字符串后会提示类似下面的错误:
    image
    这是因为,str 是局部变量,它的值是不确定的,是随机的,不知道指向哪块内存。一般情况下,这块内存要么没有访问权限,要么还没有分配,当 gets() 函数试图将读取到的字符串写入这块内存时,必然会发生错误。

    当然,如果足够幸运的话,str 也可能恰好指向一段分配好的、并且有读写权限的内存,程序就运行成功了,但这是小概率事件,一般不会发生。

    指向释放掉的内存

    请继续看下面的代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(){
        char *str = (char*)malloc(20*sizeof(char));
        strcpy(str, "C语言123456");
        puts(str);
        free(str);
        if(str){
            puts(str);
        }
        return 0;
    }
    

    运行程序,第一次输出C语言123456,第二次输出的是乱码或者什么也不输出。这是因为,free() 只是释放掉了动态分配的内存,但并未改变 str 的值,str 的值不是 NULL,它仍然指向被释放掉的内存,所以会执行 if 语句里面的 puts() 函数。但由于此时的内存已经被释放掉了,原来的字符串已经不在了,所以输出的数据是未知的。

    这就提醒我们,使用 free() 释放内存的同时要将指针置为NULL,否则下次就无法判断指向的内存是否有效。

    还有一种情况是函数外部指针指向函数内部的变量、数组等,请看下面的代码:

    #include <stdio.h>
    void func(char **pp);
    int main(){
        char *pstr;
        func(&pstr);
        puts(pstr);
        return 0;
    }
    void func(char **pp){
        char arr[] = "C语言";
        *pp = arr;
    }
    

    arr 数组在栈上分配内存,字符串"C语言"就存储在这里,func() 函数运行结束后,这块内存被释放掉,但是函数外部的 pstr 仍然指向这里,所以执行puts(pstr);时,输出结果是未知的。

    规避野指针

    要想规避野指针,就要养成良好的编程习惯:

    1. 指针变量如果暂时不需要赋值,一定要初始化为NULL,因为任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的。

    2. 当指针指向的内存被释放掉时,要将指针的值设置为 NULL,因为 free() 只是释放掉了内存,并为改变指针的值。

  • 相关阅读:
    初识人工智能(二):机器学习(三):sklearn数据集
    初识人工智能(二):机器学习(一):sklearn特征抽取
    Python3标准库:json JavaScript对象记法
    Python3标准库:uuid 全局唯一标识符
    Python3标准库:http.cookies HTTP cookie
    Python3标准库:base64 用ASCII编码二进制数据
    Python3标准库:urllib.robotparser Internet蜘蛛访问控制
    初识人工智能(一):数据分析(四):pandas数据分析
    ubuntu18.04.4安装k8s
    elasticsearch7.5.0+kibana-7.5.0+cerebro-0.8.5集群生产环境安装配置及通过elasticsearch-migration工具做新老集群数据迁移
  • 原文地址:https://www.cnblogs.com/still-smile/p/14900619.html
Copyright © 2011-2022 走看看