c - 奇怪的行为c自愿溢出

标签 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);
}

我想用 b 地址覆盖 a 以测试 c 溢出,但是当我注释第 5 行(printf 函数)时,我无法在 a 中写入 5 个。而如果我打印地址,我可以在一个地址中写五个。 为什么? 抱歉我的英语不好,谢谢。

最佳答案

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

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

C 标准均未定义此行为。这是您使用的特定编译器和编译时使用的开关的结果。

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

关于c - 奇怪的行为c自愿溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47091859/

相关文章:

c - 使用信号量交换两个 fork 进程

c - 用 c 修复百分比计算器?

c - 如何在 C 中声明和初始化 4 维数组

jasper-reports - 碧 Jade 报告 : How to print multiple lines with fixed line spacing wrapped in a text field in fixed height without stretch?

css - 单行(一个或两个单词)溢出到 div 之外

html - 页面不会溢出

CSS。 3 列布局,带有固定位置的侧列

c - 何时以及为何使用 malloc

c - 如何设置 KDevelop 才能正确使用 gcc 编译代码?

CSS使内部 float 元素的非 float 容器高度