zoukankan      html  css  js  c++  java
  • 内存越界与相邻内存覆盖问题

    先上一段代码:

    int i;

    int a[10];

    for(i=0; i<=10; i++)

    {

      a[i] = 0;

    }

     

    根据ANSI C标准规定:数组中实际不存在的“溢界”元素的地址位于数组所占内存之后,可以对这个地址赋值和比较,但是不能引用该元素。

     

    在我的机器上,得到:

    &i         = 0x22ff4c

    &a[10] = 0x22ff38

    &a[15] = 0x22ff4c

     

      可以看出,在这机器上,编译器按照内存地址递减的方式来给变量分配内存,变量i在数组a之后,按以上结果来看,编译器给数组多分配5个元素的内存,但是,如果在某些机器上,编译器严格按需分配,那么对a[10]操作就是对变量i操作,这并不是我们所需要的。此时,本来循环计数器i的值为10,循环体内将不存在的a[10]设置为0,实际上却是将计数器i的值设置为0,这就陷入了一个死循环。如下图所示:

     

    再看一例:

    main()

    {

      int i;

      char c;

      for(i=0; i<5; i++)

      {

             scanf(“%d”, &c);

        printf(“%d”, i);

      }

      printf(“ ”);

    }

     

    这个程序从标准设备读入5个数,在标准输出设备上写5个数,在我的机器上,效果如下:

    0 1 2 3 4

    0 0 0 0 0 0 1 2 3 4

    0 0 0 0 0 0 1 2 3 4

    0 0 0 0 0

    黄色的是输入,将这样一直循环下去。为什么呢?这里c被声明为char类型,而不是int类型。然而scanf函数并不能分辨接受的是int*(指针)还是char*(指针),只是将这个指针当成是指向整数的指针来接受,并把指针指向的位置存储一个整数。但是,整数所占的存储空间要大于字符所占的存储空间,所以字符c附近的内存将被覆盖。

    如果编译器按照内存地址递减的方式来给变量分配内存,整数变量i在字符变量c之后,因此每次读入一个数值到c时,i的低位部分被覆盖为0,i的高位部分本来为0,所以变量i为0,相当于每次i都被重设为0,一直循环。如下图所示:

     

    在我的机器上,得到:

    &c = 0x22ff53

    &i  = 0x22ff54

     

    总结一下:

      两个例子的原理一样,都是由于内存的“溢出”对相邻内存的覆盖,只是他们的表现的形式不同。它们有一个相似之处,能通编译器,却对程序造成致命伤害,都是难于发现的bug。

     

  • 相关阅读:
    I.MX6 sdio 设备注册及识别
    linux串口查看命令
    连词
    相形-声似词汇
    replace A with B是用A代替B还是用B代替A?
    无监督、弱监督、半监督、强化、多示例学习是什么
    JS散度(Jensen-Shannon)
    embedding是什么
    httpclient: 设置请求的超时时间,连接超时时间等
    httpclient工具使用(org.apache.httpcomponents.httpclient)
  • 原文地址:https://www.cnblogs.com/guanguangreat/p/6140515.html
Copyright © 2011-2022 走看看