CSAPP中有意思的代码集锦-001

一、 内存引用Bug

#include <stdio.h>

typedef struct
{
    int a[2];
    double d;
} struct_t;

double fun(int i)
{
    volatile struct_t s;
    s.d = 3.14;
    s.a[i] = 1073741824;
    printf("%lf\n", s.d);
    return s.d;
}

int main()
{
    fun(0);
    fun(1);
    fun(2);
    fun(3);
    fun(4);
    fun(5);
    // fun(6);
    return 0;
}

runing till fun(5)
由上图我们可以看到,s.d的值被改变了,同时,本应该i=5的地方莫名其妙地出现了s.d的值。
并且,当运行到fun(6)时,我们得到内存访问错误的提示。
fun(6) err

二、Bug产生的原因

通过分析,上述Bug一共导致了两个不寻常的现象。

  1. 结构体中的值被改变。
  2. 内存访问错误。

Bug产生的原因与数据在内存中的分布和内存访问的方式有关。在C和C++中,地址的访问不会做边界检查,因此,当访问越界,我们不会得到编译器的警告。以下是一个结构体内存分布示例:
explanation of fun
图片来源csapp第三版
从图中我们可以看到,该结构体一共被分配了7个块,每个块4个字节。当i=0,1时,我们得到的是a[0]和a[1]的正常访问结果;当i=2,3时,我们访问到的是s.d的两块4字节内存块,所以当我们改变值时,改变的其实是s.d地址下的数据;之后,当访问到i=6时,我们修改了结构体内存中关于程序状态的某些数据,这些修改导致了某些问题使程序无法继续执行下去。于是我们得到了上图测试中的那个error。
综上所述,内存引用bug的原因算是找到了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值