虚拟地址:四个对齐的倍数 - 写入地址 "in between"

Virtual addresses: multiple of four aligned - writing to address "in between"

在执行某些程序时,我意识到虚拟地址总是四的倍数(假设 32 位虚拟地址)。示例:

int main()
{
   int a = 7;
   int b = 10;
   printf("%p %p", &a, &b);
}

会给出如下内容:

它们之间的差总是四。 现在我尝试了这个:

int main()
{
    int a = 7; 
    int b = 10;
    int *y = &b;
    int yi = (int)y;
    yi--;
    y = (int*)yi;
    printf("%p %p: %d\n", &b, y, *y);
    *y = 7;
    printf("%p: %d\n", y, *y);
}

一个示例输出是:

0xffe460a0 0xffe4609f: 2807

0xffe4609f: 7

这是怎么回事?当我尝试向不是四的倍数的地址写入内容时,引用了什么?这个2807哪里来的?会不会出现页面错误?

把y当成int(64位系统危险)

int yi = (int)y;

将其地址递减为整数而不是指针 - 将导致它变得未对齐。

yi--;

将新整数硬编码为指针 - 现在使用该指针可能非常危险

y = (int*)yi;

取消引用未对齐的指针。这将根据内存控制器在不同的系统上做不同的事情。充其量,它会立即出现段错误,因此您无法做出任何假设。

printf("%p %p: %d\n", &b, y, *y);

在未对齐的内存上踩点更多的乐趣 - 为什么不呢。

*y = 7;

2807从哪里来?它是内存控制器想要给你的任何东西。也许是栈前面的垃圾值,也许是下面这个词的桶移位值,完全是系统的选择。

这就是@kaylum 在他的 UB 评论中的意思。