内存篇之越界访问

    由于C语言指针高度灵活和自由,导致内存操作中陷阱很多,比如之前的堆泄漏,栈溢出,野指针等,此外还有一种常见的“内存访问越界”错误。广义讲,栈溢出也属于内存越界,只是对同一问题站在不同角度的说法。下面看几个内存越界的例子:

    void test1()

    {

      char string[10];

      char* str1 = "0123456789";

      strcpy( string, str1 );

    }

    程序中遗忘了字符串最后隐藏的终止符’\0’,导致内存访问范围超出数组string的边界,这就是内存越界的一种。而下面是由于循环体的边界条件设置失误导致了访问越界:

    void test2()

    {

      int tab1[10] = {………};

      for(int i = 0; i<=10; i++)

      {

        tab[i] =tab1[i]*tab1[i];

        printf(“.....”);

      }

    }

    由于循环上限设置错误,最后一次循环的tab[10]超出数组界限,访问了越界的内存。

    这两个例子都是栈内存越界,就是之前栈溢出中的第一种情况(stack buffer overflow)。如果把tab1的分配方式改成int *tab1 = malloc(10),后面发生的就是堆内存越界;而如果把int tab1[10] = {…};定义在函数test2()之外,那就既不是堆也是栈,而是全局数据区的访问越界。各种内存角色越界导致的种种说法可能造成混淆,所以统称内存越界。

    内存越界危害很大,被越界覆盖的内存其功能往往是随机的,越界结果也就不可预料。比如上面test1函数,执行strcpy可能没错,但此时正常的栈内存已经被越界操作破坏,继续运行的结果可能是跳到非法指令抛出异常,或是函数返回值错误,或者执行其他地址的代码,这取决于栈的内容和排列方式。一些病毒程序就是通过有意识的内存越界,覆盖栈中的函数返回地址,从而半路拦截程序去执行恶意代码。

    有时尽管内存越界,但由于当时越界覆盖的恰好是一块空白内存,表面看程序运行一切正常。可这样反而更糟,因为错误可能逃脱测试的检查,为软件埋下一颗不定时炸弹。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值