在执行某些程序时,我意识到虚拟地址总是四的倍数(假设 32 位虚拟地址)。示例:
int main()
{
int a = 7;
int b = 10;
printf("%p %p", &a, &b);
}
会给出类似的东西:
- xff86c930 0xff86c934
- xfff58f80 0xfff58f84
- ...
它们之间的差总是四。 现在我尝试了这个:
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;
取消引用未对齐的指针。这将根据内存 Controller 在不同的系统上做不同的事情。充其量,它会立即出现段错误,因此您无需做出任何假设。
printf("%p %p: %d\n", &b, y, *y);
在未对齐的内存上踩点更多的乐趣 - 为什么不呢。
*y = 7;
2807从何而来?它是内存 Controller 想要给你的任何东西。也许是栈前面的垃圾值,也许是下面这个词的桶移位值,完全是系统的选择。
这就是@kaylum 在他的 UB 评论中的意思。
关于c - 虚拟地址 : multiple of four aligned - writing to address "in between",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37061100/