奇怪的行为c自愿溢出

时间:2017-11-03 09:03:10

标签: c overflow

这是代码:

#include <stdio.h>
#include <stdlib.h>
int main() {

    int a = 10;
    int b = 20;
    //printf("\n&a value %p", &a);
    int* x = &b;

    x = x + 1;

    *x = 5;

    printf("\nb value %d", b);
    printf("\na value %d", a);
}

我想覆盖a和b地址来测试c溢出但是当我评论第5行(printf功能)时我不能写入5。如果我打印一个地址,我可以写一个五。 为什么? 对不起我的英文,谢谢你。

2 个答案:

答案 0 :(得分:1)

发生这种情况的原因是,所有正常编译器都会在堆栈上存储具有自动存储持续时间(在块中声明为非staticextern的对象)的对象。您的编译器将a“推送”到堆栈上,这意味着它将a写入堆栈指针指向的内存位置,然后递减指针。 (减少指针会增加堆栈,因为堆栈会朝着减少内存地址的方向增长。堆栈可以朝向另一个方向,但您观察到的行为强烈建议您的系统使用向下增长的共同方向。)然后,编译器将b推入堆栈。因此,b最终位于a下方的内存地址。

当您获取b的地址并添加一个时,会产生a所在的内存地址。当您使用该地址分配5时,该值被写入a所在的位置。

这种行为都不是由C标准定义的。这是您使用的特定编译器和编译的开关的结果。

您可能很少或根本没有优化编译。启用优化后,许多编译器会通过删除不必要的步骤(基本上用快捷方式替换它们)来简化代码,因此20和10实际上并不存储在堆栈中。优化的可能结果是打印“20”和“10”,您对*x的分配无效。但是,C标准没有说明以这种方式使用*x时必须采取的行为,因此结果仅由您使用的特定编译器以及您提供的输入开关确定。

答案 1 :(得分:-1)

x = x + 1;之后,x包含您不拥有的地址。通过执行*x = 5;,您尝试写入某些可能无法访问的位置。从而导致UB。没有更多的理由可以解释。