c++ - 内存引用错误示例

标签 c++ c cpu-architecture

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;
    return s.d;
}

enter image description here

我在学习CSAPP类(class)时遇到了这个例子。解释如下所示。但我还是想不通。 enter image description here

最佳答案

让我们看看你的结构在内存中是什么样子的。假设 int 是 4 个字节(因为这就是最终行为让我们相信的),如下:

byte 0,1,2,3: a[0]
byte 4,5,6,7: a[1]
byte 8,9,A,B,C,D,E,F: d

fun(1) 创建此结构,将 d 设置为 3.14 (0x40091EB851EB851F),然后设置 a[i] 1073741824 (0x40000000)。没有运行时检查来确保 a[i] 指向 a[2] 内的位置,这可能会导致问题(如此处所示)。 0 和 1 不会改变任何内容,因为两者都会分别写入 a[0]a[1]。但是,如果您写入 a[2],则会与 d 占用的空间重叠。通过写入 a[2],您可以替换 d 的前 4 个字节。

请注意,您系统上的大小可能有所不同,例如int 可能是 2 个字节,但问题的要点是相同的。

最终,当到达 a[4] 时,d 返回到 3.14。这是因为你已经完全跨过了d。超出此点的堆栈未分配,因此程序因段错误而终止。

TL;DR:您正在写入与您的替身重叠的内存。

(注意 - 这是一个不该做什么的示例。这是未定义的行为,并且不能保证给定系统在这种情况下会做什么。)

关于c++ - 内存引用错误示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45125075/

相关文章:

c++ - 最烦人的解析

c - 本地定义的数组在其定义的函数之外有效吗?

c - realloc() 时指针无效

cpu - Sandy-Bridge CPU 规范

assembly - x86在x86-x64中不同或已完全删除的32位操作码

c++ - 如何使用区域增长算法来定义感兴趣区域?

c++ - 将 std::wstring 转换为 SQLWCHAR *

x86 - CPU如何处理异步中断?

c++ - 使用 Xcode 9.0 with clang 时出现编译错误(生成多个输出文件时不能指定 -o)

c++ - 为什么这个程序是用 gcc 编译的,而不是用 g++ 编译的?