您的位置:首页 > 编程语言 > C语言/C++

C语言中数组越界的例子

2015-07-26 10:33 302 查看
前几天在论坛闲逛,偶然发现了一个帖子,说的是数组输出的问题,

学习了,后面经过自己的查找,发现确实有这个情况。主要是因为初学者对于数组的定义还不清楚,数组的第一个位置应该是0开始的,但是往往会从自己的习惯来定义数组的使用,所以就造成“奇怪”结果。

比如下面的这个例子

#define num 10
int a[num];
我们都知道 使用的时候只有 a[0] 到 a[9]  这10个变量;
同时也知道使用a[10]属于数组越界,平时应该避免这么用;
......
但是, a[10]的值到底是多少?a[10] = 10; 
当然 a[11],a[12]等等都是毫无意义的了;
经测试 num = 10, 100, 1000...时,
a[10] = 10; a[100] = 100; a[1000] = 1000;...

求详细解答~ a[num] = num; 
关键问题是可否将该语句应用到实际编程中去?

我觉得大伙曲解了我的意思,个人觉得这个应该和数组声明,以及堆栈有关,能否从这个角度给个解答?
另外10,100,1000指的是修改 #define num 10 这个宏~~!

 

内存给num分配的存储位置紧跟数组a后面,在printf(“%d”, a【num】)时输出了数组a后面地址上的内容,即num的值,该值只读不可修改
追问:

的确,根据不同的环境,改值是会随机发生变化,和我猜想的一样,越界只是访问到了a[num]的这个num所在的位置,才造成的这一结果;谢谢大伙了,但是只能有一个最佳;

追答:

我也用gcc编译器,打印的a【num】是num的值,这一假设的确成立
只是不知道是否可以当成一个惯例来使用

提问者评价
C语言漏洞多多,但是我们得知其所以然!!!

 又比如下面这个精心的例子。

大家都知道,在C语言中一般是不会检查数组的下标范围的,这样的好处是给了程序员很大的灵活性,更宜于写出高效的代码。如果定义一个数组a
,其有效下标范围为0 - (n-1),但你要引用下标n,编译器一般是不提示错误的,但是这样也潜在的隐含着一些隐患。

请看如下语句:(32位机器上)

#include <stdio.h>

int main(void)

{

    int i;

    int a[3] = {1, 2, 3};

    

    for (i = 1; i <= 3; i++)

    {

        a[i] = 0;

    }

    return(0);

}

现在我们假设计算机分配给变量i内存位置为0022FF5C

数组a中各元素所分配的内存位置如下:

a[0]地址:0022FF50

a[1]地址:0022FF54

a[2]地址:0022FF58

请看for()循环:

i = 1时,把a[1]置0。i自加一次变为2,把a[2]置0。i再自加变为3。

注意了!!!

当i变为3时,程序将找到数组元素a[3]所在的内存位置(即本例中分配给变量i的内存单元0022FF5C),并写入0,从而导致变量i值为0。接着到for()循环中去判断条件 i <= 3,因为i的值刚才被置为0,i <= 3成立,导致再次开始执行循环。

就后程序将陷入死循环。

这就是C中数组不检查下标的一些隐患。但是现在众多的编译器已经对此缺陷做了设计上改良和优化。

平时写一些有关数组的程序时,对数组的元素个数,最好是采取宏定义的方式,比如#define N 10,或是先把元素个数留空(留空时要记得一定要初始化哦),在用到数组元素个数的时候用sizeof方法计算一下就可以了。比如本例子中可以用sizeof(a)/sizeof(a[0])来计算出数组中所包含的元素的个数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: