加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 站长资讯 > 传媒 > 正文

10 个内存引发的大坑

发布时间:2021-04-08 12:00:18 所属栏目:传媒 来源:互联网
导读:很多同学并不知道这样写会有什么问题,因为上述代码有时并不会出现运行时错误。 原来 scanf 会将a的值当做地址来对待,并将从标准输入中获取到的数据写到该地址中。这时接下来程序的表现就取决于a的值了,而上述代码中局部变量a的值是不确定的,那么这时:

很多同学并不知道这样写会有什么问题,因为上述代码有时并不会出现运行时错误。

原来 scanf 会将a的值当做地址来对待,并将从标准输入中获取到的数据写到该地址中。这时接下来程序的表现就取决于a的值了,而上述代码中局部变量a的值是不确定的,那么这时:

如果a的值作为指针指向代码区或者其它不可写区域,操作系统将立刻kill掉该进程,这是最好的情况,这时发现问题还不算很难

如果a的值作为指针指向栈区,那么此时恭喜你,其它函数的栈帧已经被破坏掉了,那么程序接下来的行为将脱离掌控,这样的 bug 极难定位

如果a的值作为指针指向堆区,那么此时也恭喜你,代码中动态分配的内存已经被你破坏掉了,那么程序接下来的行为同样脱离掌控,这样的bug也极难定位

上述代码的错误之处在于假设从堆上动态分配的内存总是初始化为 0,实际上并不是这样的。我们需要知道,当调用 malloc 时实际上有以下两种可能:

如果 malloc 自己维护的内存够用,那么 malloc 从空闲内存中找到一块大小合适的返回,注意,这一块内存可能是之前用过后释放的。在这种情况下,这块内存包含了上次使用时留下的信息,因此不一定为0

如果 malloc 自己维护的内存不够用,那么通过 brk 等系统调用向操作系统申请内存,在这种情况下操作系统返回的内存确实会被初始化为0。原因很简单,操作系统返回的这块内存可能之前被其它进程使用过,这里面也许会包含了一些敏感信息,像密码之类,因此出于安全考虑防止你读取到其它进程的信息,操作系统在把内存交给你之前会将其初始化为0。

现在你应该知道了吧,你不能想当然的假定 malloc 返回给你的内存已经被初始化为 0,你需要自己手动清空。

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读