C 虚拟地址:四个对齐地址的倍数-写入地址“;在两者之间;
当执行一些程序时,我意识到虚拟地址总是四的倍数(假设32位虚拟地址)。例如:C 虚拟地址:四个对齐地址的倍数-写入地址“;在两者之间;,c,paging,memory-address,virtual-memory,C,Paging,Memory Address,Virtual Memory,当执行一些程序时,我意识到虚拟地址总是四的倍数(假设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
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位系统上很危险)
将其地址递减为整数而不是指针-将导致其未对齐
yi--;
硬代码将新整数作为指针返回-现在使用该指针可能非常危险
y = (int*)yi;
取消对未对齐指针的引用。这将在不同的系统上执行不同的操作,具体取决于内存控制器。充其量,它会立即隔离故障,这样您就不会做出任何假设
printf("%p %p: %d\n", &b, y, *y);
为了好玩,在未对齐的内存上多踩一些——为什么不呢
*y = 7;
2807从哪里来?它是内存控制器想要给你的任何东西。也许它是堆栈中较早的垃圾值,也许它是下面这个词的桶移位值,它完全是系统的选择
这就是@kaylum在UB评论中的意思。
虚拟地址总是四的倍数true@kaylum是否出现页面错误@今天春天 即使我们假设这个架构——它不是真的——你能纠正我的说法吗?解释未定义的行为是没有意义的。要准确解释发生了什么,需要分析程序集和内存布局。这两者都可能因操作系统、源代码、使用的编译器、使用的编译器标志、加载程序、内核等的不同而发生变化。这一切都取决于您的环境,其他任何人都无法直接复制。这不是一个有效的练习。@Michael,为什么内存需要与32字节对齐(在32位处理器上),为什么有这个限制。。。。我的疑问是处理器一次不读取32位,它读取缓存线块,所以为什么需要32位对齐??它应该取决于缓存线对齐。
*y = 7;