C++不会自动检查数组越界,也就是说如果数组越界,程序编译时不会报错,从而在执行时产生非法操作或者得不到正确的结果。因此在使用数组时,一定要在编程中判断是否越界以保证程序的正确性。


面试例题8:改错--数组越界

考点:数组越界出现的问题。

出现频率:★★★★

题(1)

1    void test1()
2    {
3        char string[10];
4        char* str1 = "0123456789";
5        strcpy(string, str1);
6    }

题(2)

1    void test2()
2    {
3        char string[10], str1[10];
4        int i;
5        for(i=0; i<10; i++)
6        {
7            str1[i] = 'a';
8        }
9        strcpy(string, str1);
10   }

题(3)

1    void test3(char* str1)
2    {
3        char string[10];
4        if(strlen(str1) <= 10)
5        {
6            strcpy(string, str1); 
7        }
8    }

解析:

这3道题都有数组越界的问题。

题(1)中,string是一个含有10个元素的字符数组,str1指向的字符串长度为10,在进行strcpy调用时,会将str1的结束符也复制到string数组里,即复制的字符个数为11,这样会导致string出现数组越界。程序不一定会因此而崩溃,但这是一个潜在的危险。解决办法是将string的元素个数定义为11。

题(2)中,str1和string都是含有10个元素的字符数组,并且str1的元素全部被赋为字符"a",然后再调用strcpy。这里会出现以下两个问题:一个问题是str1表示的字符数组没有以'/0'结束,在随后调用strcpy时无法判断什么时候复制结束;另一个问题是string的数组长度不够,出现数组越界的现象。解决办法是将string和str1的元素个数都定义为11个,并在调用strcpy之前加入一条语句把str1[10]赋为'/0'。

题(3)中,if语句使用小于等于"<="进行比较,如果str1的长度等于10,也会出现数组越界的情况。解决办法是把"<="换成"<"。

答案:

3道题都有数组越界的问题。改正后的程序如下所示。

题(1)

1    void test1()
2    {
3        char string[11];           //字符数组长度为11,多分配一个
4        char* str1 = "0123456789";
5        strcpy(string, str1);
6    }

题(2)

1    void test2()
2    {
3        char string[11], str1[11];   //字符数组长度都为11,均多分配一个
4        int i;
5        for(i=0; i<10; i++)
6        {
7            str1[i] = 'a';
8        }
9        str1[10] = '/0';            //初始化str1为空字符串
10       strcpy(string, str1);
11   }

 

       题(3)

1    void test3(char*str1)
      2    {
      3        char string[10];
      4        if(strlen(str1) < 10)        //不能用<=
      5        {
      6            strcpy(string, str1); 
      7        }
      8    }

 


      面试例题9:分析程序--数组越界

      考点:不当的循环操作导致数组越界。

      出现频率:★★★

      下面这个程序执行后会出现什么错误?

1    #define MAX 255
      2    int main()
      3    {
      4        unsigned char A[MAX], i;
      5    
      6        for (i = 0; i <= MAX; i++)
      7            A[i] = i;
      8    }

      解析

      代码第6行的for循环中用的是"<=",当i=MAX时数组越界。值得注意:这个程序很容易使人误认为只有数组越界的问题,但只要细心些就能发现,i是无符号的char类型,它的范围是0~255,所以"i<=MAX"一直都是真,这样会导致无限循环。可以把"i<=MAX"改为"i<MAX",这样既避免了无限循环又避免了数组越界。

      答案

      i<=MAX导致数组越界以及无限循环,应改为i<MAX。

 


      面试例题10:分析程序--打印操作可能产生数组越界

      考点:打印操作时可能产生的数组越界问题。

      出现频率:★★★

      下面这个程序的打印结果是什么?

1    #include <stdio.h>
      2    
      3    int main()
      4    {
      5        int a[5]={0, 1, 2, 3, 4}, *p;
      6        p = a;
      7        printf("%d/n",*(p + 4*sizeof(int)));
      8
      9        return 0;
      10   }

      答案

      这个程序存在着越界的问题。

      代码第6行,p指向a的第1个元素,所以p+4指向a的最后一个元素即4,p + 4 * sizeof(int)即p+16,此时指向的是数组a的第17个元素,显然已经越界了,因此打印结果是个随机数。