C/C++ 数组越界问题

630 阅读1分钟
#include <stdio.h>

int main()
{
    int avg = 90;
    int num[5] = {1,2,3,4,5};
    int sum = 0;
    for(int i=0;i<=5;i++)
    {
        printf("num[%d]为:%d\n", i,num[i]);
        sum = sum + num[i];
    }

    printf("sum = %d",sum);
    return 0;

}

image.png

  • 访问数组长度只有5的数组num的num[5],理论上数组越界,却没有报错。而人工计算sum的结果应该是15,运算代码得到的结果却是105。
  • 如果声明avg时将avg赋值为0,则得到sum=15的结果。

查阅资料后我得出造成这个结果的原因:

  1. 在C语言中,除访问受限的内存以外的内存空间都可以自由访问。访问数组的时候,只是根据首地址向后连续推算,只要有内存就行。所以访问num[5]时,实际上访问了num[4]后的一块内存。
  2. 在全局储存中内存分配是连续的。
  3. avg、num等在栈空间中分配内存的内存分配方式是地址递减(向下增长),即从高地址向低地址分配,也就是说,数组num在内存中地址是按序从低向高存放的,num[0]所在地址永远比num[5]低。所以当先声明average=0时,sum累加num[5]=0。而先声明num数组时,for循环所访问的num[5]则是全局储存中其他变量,而这个变量是什么难以预料。

image.png

  • 所以当在函数中先声明avg=90时,num[5]和avg的地址是相同的,导致运行得到1+2+3+4+5+90的结果。

因为在全局储存中内存分配是连续的,所以越界操作可能导致操作别的变量,进而出现难以预料的错误。