zoukankan      html  css  js  c++  java
  • 第41课

    第41课 - 内存操作经典问题分析一

    1. 野指针

    (1)野指针指的是 指针变量的值是非法的内存地址,操作野指针会导致程序运行出错。

           野指针不是NULL指针而是指向了非法地址;NULL指针并没有危害而且很好判断和调试。

    (2)C语言中无法判断一个指针所保存的地址是否合法

    (3)野指针产生的原因        ※ 写程序时一定要考虑下面这些注意点

       ● 局部指针变量没有被初始化。局部指针变量存储在栈上,如果没有初始化,指针变量的值是"垃圾值"

       ● 指针所指向的变量在指针使用之前已经被销毁了,典型的例子就是返回局部变量或者局部数组,具体原因可以参考 第39课 - 程序中的三国天下

       ● 使用 malloc() 申请的动态内存在被 free() 掉之后,仍然使用已经释放过的指针

       ● 进行了错误的指针运算,比如越界访问内存

       ● 进行了错误的强制类型转换,比如 int *p = (int *)123456;

    【野指针初探】

     1 #include <stdio.h>
     2 #include <malloc.h>
     3 
     4 
     5 int main()
     6 {
     7     int* p1 = (int*)malloc(40);  // 分配40字节
     8     int* p2 = (int*)1234567;     // 错误的强制类型转换, 123456是一个非法地址
     9     int i = 0;
    10     
    11     for(i = 0;i < 40; i++)
    12     {
    13         *(p1 + i) = 40 - i;  // p1只分配了40字节,这里越界访问(40 * 4)字节
    14     }
    15 
    16     free(p1);
    17 
    18     for(i = 0; i < 40; i++)
    19     {
    20        p1[i] = p2[i];   // p1越界访问 + p1已经释放,p2非法内存
    21     }
    22 
    23     return 0;
    24 }

    2. 基本原则

    (1)绝不返回局部变量和局部数组的地址

    (2)任何变量在定以后必须初始化为 0

    (3)字符数组必须以 '' 结束符后才能成为字符串

    (4)任何使用与内存操作相关的函数必须指定长度信息

    【无处不在的野指针】

     1 #include <stdio.h>
     2 #include <malloc.h>
     3 #include <string.h>
     4 
     5 struct Student
     6 {
     7     char* name;
     8     int number;
     9 };
    10 
    11 char* func()
    12 {
    13     char p[] = "Hello World!";
    14     return p;  // 返回局部数组
    15 }
    16 
    17 void del(char* p)
    18 {
    19     printf("%s
    ", p);
    20     free(p);
    21 }
    22 
    23 int main()
    24 {
    25     struct Student s;  // 结构体没有初始化
    26     char* p = func();  // 返回局部的数组地址
    27 
    28     // strcpy(s.name, p);  // s结构体中的name是野指针
    29 
    30     s.number = 99; // 合法
    31 
    32     p = (char*)malloc(5);
    33 
    34     strcpy(p, "Hello World!");  // 内存越界访问
    35 
    36     del(p);
    37 
    38     return 0;
    39 }

    内存错误是实际产品开发中最常见的问题,然而绝大多数的bug都可以通过遵循基本的编程原则和规范来避免。因此,在学习的时候要牢记和理解内存操作的基本原则、目的和意义!!!

    1

  • 相关阅读:
    RedHat的定制安装
    Linux系统概述
    嵌入式学习方法
    mysql联合查询
    mysql之count
    memcached安装
    css书写规则
    nginx的fastcgi_param参数详解
    array_2.array_rand
    array_1.array_map
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/11854031.html
Copyright © 2011-2022 走看看