c - 虚拟地址 : multiple of four aligned - writing to address "in between"

标签 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 *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/

相关文章:

c - 使用有限的工具、没有数组和库函数评估简单的数学表达式

c - 用于上下文切换的 gcc 内联汇编

c - C 中嵌套结构类型和复制函数的内存泄漏

c - 如何通过分段或分页防止缓冲区溢出?

c - 正确的格式说明符以打印指针或地址?

c - C 中这个表达式 (char *) 是什么意思?

c - 执行快速排序时使用 GCC 编译器在 C 中出现段错误

mysql - 分页结果 : Handling invalid passed data

javascript - SharePoint 2013 - Javascript - 客户端分页 - 使用 listitemcollectionposition

assembly - I/O地址空间如何映射到设备?