【C/C++】数组访问越界,变量被异常修改问题

有些语言本身就会做数组访问越界检查,比如java,访问越界时会抛出java.lang.ArrayIndexOutOfBound.
C语言非常重视运行时的效率,所以没有进行数组越界检查,而C++继承了C的效率要求,也不做数组越界检查。

这样就会造成对未知内存的修改,带来很多意想不到的问题,造成重大影响,这类问题往往debug的时候也比较难以发现。


int main(int argc, char* argv[]){
    int i = 0;
    int array[3] = {0};
    for(; i<=3; i++){
        array[i] = 0;
        printf("hello world\n");
    }
    return 0;
}

在部分编译器下,这个代码执行后是会陷入死循环的。
原因在于数组越界之后,修改的array[3]其实修改的内存是i所在,i被改成0,循环从头开始,如此往复。

分析

原来觉得根据栈帧结构,应该是地址从高到低放置变量,然后访问到了最先定义的在高地址的变量i,但是换了一下 int i = 0;的位置,还是死循环。

后来了解到,不同编译器是不同的,同时这也跟地址对齐方式有关,把array[3]改成array[4]之后,再修改循环条件<=4,也不会再发生死循环了。

解决方式

1

最简单,写的时候注意不要出错。或者,手动加一段代码,检查是否越界,不过这样确实会增加开销,影响效率。

2

gcc编译的时候是有 堆栈保护的选项的,会进行一些保护操作,比如强制将数组放在函数栈的高地址,而将其他变量放在低地址。

增加 -fstack-protector-all 就能为所有函数插入保护代码。

当然,这也有一些局限性,最好还是写代码的时候就注意保护。

具体可以查看 https://www.ibm.com/developerworks/cn/linux/l-cn-gccstack/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值