标题:Linux GCC 对数组到底是怎么处理的?
只看楼主
q332010372
Rank: 2
等 级:论坛游民
帖 子:52
专家分:61
注 册:2010-7-27
结帖率:44.44%
已结贴  问题点数:20 回复次数:16 
Linux GCC 对数组到底是怎么处理的?
int main(void)
{
   int arr[5], i;
   for(i = 0; i < 9; i++)
   {
      arr[i] = i;
      printf("i = %d, arr[%d] = %d\n", i, i, arr[i]);
   }
   return 0;
}

当 i < 9 时,运行后并不会出错,但 >=9 时,就会出错。从安全性来说 ,应该要在 i 超过 4 的时候就应该出错了 ,但它并不出错。GCC 到底是怎么处理数组越界这问题的?

搜索更多相关主题的帖子: void 问题 return 安全性 Linux 
2012-04-15 22:49
embed_xuel
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:58
帖 子:3845
专家分:11385
注 册:2011-9-13
得分:0 
去搜一下数组下标吧,我手机上不好长篇大论

总有那身价贱的人给作业贴回复完整的代码
2012-04-15 23:46
S_Ringo
Rank: 4
来 自:歌舞伎町
等 级:业余侠客
帖 子:94
专家分:230
注 册:2012-4-15
得分:0 
gcc-4.1对数组越界并没有进行干涉,当数组越界发生时,会出现segmentation fault错误,然而gcc-4.3.2以后对数组越界进行了优化,譬如:定义了数组tmp[100],当越界操作出现后,访问会被限制在数组边界上,即访问tmp[102]会最终限制为tmp[99],不会真正发生越界。

嘿嘿,刚在网上看到的……希望有用
网址:http://lion3875.blog.
2012-04-16 08:32
q332010372
Rank: 2
等 级:论坛游民
帖 子:52
专家分:61
注 册:2010-7-27
得分:0 
你这文章,我也在网上看过,但是我觉得这是错误的,下面是运行结果:
/*在 ubuntu gcc 上的结果*/
tancen@Tancen:~/mydoc/work/c/try$ ./try
i = 0, arr[0] = 0
i = 1, arr[1] = 1
i = 2, arr[2] = 2
i = 3, arr[3] = 3
i = 4, arr[4] = 4
i = 5, arr[5] = 5
i = 6, arr[6] = 6
i = 7, arr[7] = 7
i = 8, arr[8] = 8
tancen@Tancen:~/mydoc/work/c/try$
如果你看到的文章是正确的,那么 arr[4] 以后的空间是访问不到的,因为已经越界了。另外,还有一件很奇怪的事情,当程序访问 arr[9] 这个位置的时候,终端会提示 “段错误”,根据我的理解,应该是 arr[9] 这个位置,越过了 try 这个程序数据段的边界了。如果我的理解是正确的话,那么,是不是说 linux gcc 根本就不对数组越界进行检测,直到系统强行终止这个异常的程序呢?
2012-04-16 12:45
flyxkj
Rank: 2
等 级:论坛游民
帖 子:15
专家分:66
注 册:2012-1-31
得分:0 
理论上是有问题!但是段错误这个是随机!如果没有覆盖到其他数据的空间,程序运行是没有问题的!
但是把代码改成下面,那就一定触发段错误
#include <stdio.h>
#include <stdlib.h>

void show( void )
{
        printf( "Hello,World!\n" );
}
int main( void )
{
        int arr[5], i;
        void (*p)(void) = show;
        for( i = 0; i < 9; i++ )
        {
                arr[i] = i;
                printf( "i = %d, arr[%d] = %d\n", i, i, arr[i] );
        }
        p();
        return EXIT_SUCCESS;
}
因为把函数指针的值给覆盖了!
2012-04-16 16:57
q332010372
Rank: 2
等 级:论坛游民
帖 子:52
专家分:61
注 册:2010-7-27
得分:0 
回复 5楼 flyxkj
按照你这样说,那么 GCC 似乎完全不检测数组越界,直到程序出现错误,被系统强行终止。
这是一个噩梦!

int main( void )
{
        int arr[5], i;
        void (*p)(void) = show;
        for( i = 0; i < 6; i++ )
        {
                arr[i] = i * 2;
                printf( "i = %d, arr[%d] = %d\n", i, i, arr[i] );
        }
        p();
        return EXIT_SUCCESS;
}

/* 运行在 ubuntu gcc - 4.6.1 上的结果
i = 0, arr[0] = 0
i = 1, arr[1] = 2
i = 2, arr[2] = 4
i = 3, arr[3] = 6
i = 4, arr[4] = 8
i = 10, arr[10] = 1216787
Hello,World!
*/
2012-04-16 20:15
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
C语言本身就不检查越界,不是什么GCC的问题,任何C/C++编译器都不检查,也检查不出来。

授人以渔,不授人以鱼。
2012-04-16 20:17
q332010372
Rank: 2
等 级:论坛游民
帖 子:52
专家分:61
注 册:2010-7-27
得分:0 
回复 7楼 TonyDeng
编译器是不会在编译期间检查,但是在发生越界的时候,应该要报错才对。这段代码在 windows vs 10.0 里面是会出错的,但在linux gcc 里面并不会出错
2012-04-16 20:49
q332010372
Rank: 2
等 级:论坛游民
帖 子:52
专家分:61
注 册:2010-7-27
得分:0 
难道因为 vs 是在 debug 之后再生成可执行文件,gcc 本身不存在所谓的 "debug",才需要用到 lint ?
2012-04-16 20:52
flyxkj
Rank: 2
等 级:论坛游民
帖 子:15
专家分:66
注 册:2012-1-31
得分:0 
回复 6楼 q332010372
事实上本来!编译器怎么会检测出越界!越界错误本身就属于运行时错误一类的!
2012-04-16 20:57



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-365877-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.540526 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved