【问题标题】:Could memory addresses be corrupted, because of unaligned memory address? [closed]由于未对齐的内存地址,内存地址是否会损坏? [关闭]
【发布时间】:2020-03-25 11:05:28
【问题描述】:

所以,当我试图访问这个0x303030303a303030 地址时。我收到了SIGBUS 错误。

“正常/有效”地址的类型如下:0xffc8613d68。 并且所有的指针都是有效的,直到发生了一些事情。

那么,是否会因为“未对齐”的内存地址而导致指针损坏?

一般来说,“未对齐”内存地址的症状是什么? 表演后的样子?

我的案例发生在 MIPS 上。

entries = {
     next = 0x36312e30382e3438, 
     prev = 0x3000300035322e31
  }
  nice_ptr = 0x303030303a303030, 
  imp_data= 0x30303a303030303a <error: Cannot access memory at address 0x30303a303030303a>, 
  nimp_data= 0x323030303a3130

【问题讨论】:

  • 您不能只访问随机内存地址,对齐或未对齐 - SIGBUS 意味着该地址没有任何内容。这是一个随机地址,为什么当你得到错误时你会感到惊讶?请参阅例如stackoverflow.com/questions/212466/…
  • 这不一定是未对齐的,它可能没有被映射,因为在访问该虚拟地址时 MMU 会说“不”。并非每个地址都实际存在。
  • @barny,我很惊讶。因为那个指针应该是有效的,但我看到了我看到的)。主要问题是,它们是如何失效的。
  • 在任何地方(在宇宙中)有人说“指针应该 [无条件] 有效”?是的,如果您声明一个变量,您可以获得指向它的有效指针,或者如果您成功 malloc() 一些内存,那么您就有一个有效的指针。然而你的代码没有做这些——你组成了指针——你不能指望它们是有效的! SIGBUS 并不奇怪。这就像一个想法,如果你不看就走在马路上,如果有车撞到你,你不应该感到惊讶。
  • @barny,当然。如果我硬编码一个地址,在一个选项中我可以获得 Segfault,在另一个更糟糕的 SIGBUS 中。所以,我想,无论如何,将硬编码地址分配给指针,这不是一个好主意。

标签: c++ c memory-management mips memory-address


【解决方案1】:

我怀疑您看到的是未定义行为的结果。很可能您的一个错误指针导致您的程序指向一页不相关的数据,您的调试器试图理解它好像它包含一个有效的数据结构,但由于它没有,您的调试器显示基于无意义的值关于误解在该位置的不相关数据。

尝试在不支持未对齐访问的 CPU 上取消引用未对齐/未对齐的地址通常会导致引发 SIGBUS 样式的陷阱。 (请注意,即使在 CPU 确实支持的 x86 等 CPU 上,未对齐/未对齐的取消引用也被视为未定义行为,在这种情况下,问题的症状可能会更加微妙,而不是明显的崩溃,您可能最终会导致计算结果不正确,或者仅在某些 CPU 上崩溃而不在其他 CPU 上崩溃)。

所以简短的回答是:不要取消引用未对齐的指针(或者,如果必须,请确保将它们转换为 const char * 或类似的,以便编译器可以执行必要的操作以允许这种访问 - 并且是非常小心你用那个指针做什么)。如果您需要将未对齐的数据(例如,来自网络数据包或加载的二进制文件)复制到对齐的 intfloat 或其他任何内容中,请通过例如memcpy(&amp;myFloat, my_unaligned_char_ptr, sizeof(myFloat)); 而不是通过未对齐的 int/float/etc 指针和赋值运算符。 memcpy() 将正确处理未对齐的取消引用,但 = 不会。

【讨论】:

  • 谢谢!我正在使用 gdb 进行调试。仅供参考)
猜你喜欢
  • 2012-04-18
  • 2013-03-08
  • 1970-01-01
  • 2018-10-22
  • 2021-09-01
  • 2019-02-19
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多