c++关于越界访问(内存溢出)

16 篇文章 0 订阅
13 篇文章 0 订阅

越界访问指访问了不是程序申请的内存区域,常见场景如下:

(1)数组越界,比如申请了5个字节的char数组,结果读写数组的第六个元素

(2)访问了释放后的内存

(3)访问野指针

(4)....。

这种错误,debug调试环境下有时抛出AV(access violation)异常,此时有的IDE能捕获此异常(有些IDE需要特殊设置才能捕获,比如BCB,需要打开 project->options->C++ Compiler->Debugging->Enable Codeguard),脱离IDE的调试环境时又捕获不到此异常,即有时不抛出异常,但此时的行为是未定义的; release环境下有时导致软件直接崩溃(类似"Abnormal program termination"),即release环境下,AV异常是无法捕获的(即使用try...catch...,无法捕获AV异常),有时运行迷失(比如越界的子线程一直没有退出,但给人的感觉是子线程卡死);而且抛出异常的地方大多不是越界访问的地方(比如下面的例子),让人摸不着头脑;不抛出异常的时候可能是因为访问了释放后的内存,虽然内存释放了,但还没被系统回收,但时间长了系统也会运行不正常;而且有时在project下的debug版本和release版本下表现的也不一样,比如有时在debug版本下直接导致软件退出,提示:Abnormal program termination,在release版本下有可能不报异常,但运行一段时间后软件还是没有按照预期运行,比如运行迷失等。以下是一个我经历的越界访问的例子:

std::string tmpStr;
...
std::string funCode=...;
...
char *tmpc=new char[len-48+1];
memset(tmpc,0,len);             //越界的地方
...
tmpStr += funCode;              //AV异常抛出的地方
...


如果你仅仅查看异常抛出的地方,只是调用std::string的operator+=函数,怎么看也看不出有什么问题! 如果你往前看就会发现我们申请了len-48+1个字节的内存空间, 但是在memeset的时候却填充了len个字节的空间, 多填充了47个字节的空间,而这个越界填充可能就非法填充了tmpStr内部的内存空间,破坏了tmpStr内部的结构,从而造成std::string在函数operator+=的时候发生了AV异常,此案例越界的地方与AV异常的地方在同一个函数内,通过代码走读还好查找一些,有些越界的地方与AV异常的地方相距甚远(不在同一个单元文件),非常不容易查找,此时就需要借助IDE或第三方工具进行排查!

std::vector 的operator [] 也是经常会造成越界访问的地方,而且下标运算符并不检测下标是否越界,越界后属于典型的未定义行为(Undefined Behavior);但vector提供了at函数,此函数提供了越界检查,如果越界,会抛出 std::out_of_range异常,通过try和catch能够捕获到(AV异常通过try和catch捕获不到)。

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值