【问题标题】:Difference between (type *)var and (type *)&var(type *)var 和 (type *)&var 的区别
【发布时间】:2021-05-07 17:43:57
【问题描述】:

我正在阅读一篇关于 Kerberos 凭据窃取的非常有趣的文章。在 PoC 中作者有以下一行:

struct inotify_event *event = (struct inotify_event *)&buffer[i];

其中缓冲区定义为

char buffer[BUF_LEN];

我想知道的是上面的这种类型转换是如何工作的,它与

(struct notify *)buffer[i];

虽然我知道要转换的类型分别是 char * 和 char,但我无法理解作者为什么以及如何将其转换为结构并随后访问它的成员

【问题讨论】:

  • (type *)var 正在转换 var 本身的值。 (type *)&var 正在将 指针投射到 var。
  • C 还是 C++?选择一个或问 2 个不同的问题。 C++ 支持运算符重载,因此代码可以做任何事情。
  • 为什么作者要进行演员表访问成员?您将如何访问成员?
  • struct inotify_event *event = (struct inotify_event *)&buffer[i]; 是未定义的行为,因为它是严格的别名违规。
  • @AndrewHenle 严格来说它不是,直到左值被取消引用为结构类型(或与有效类型不兼容的结构的任何成员)。当然,如果目的不是取消引用指针,你为什么要这样做。

标签: c pointers casting


【解决方案1】:

(type *)var 和 (type *)&var 的区别

Former 将var 的值转换为指向type 的指针。当var 包含一个表示type 对象地址的值时,这可能是合理的。鉴于在您的情况下 var 是 char,将其值重新解释为指针可能是不合理的。

后者将指向var 的指针转换为指向type 的指针。当 var 及其同级表示您希望解释为 type 的值时,这可能是合理的。

【讨论】:

    【解决方案2】:

    (type*)var 通常是编译器错误,除非var 是整数类型。整数可以通过特殊规则 C17 6.3.2.3/5 转换为指针:

    整数可以转换为任何指针类型。除先前规定外, 结果是实现定义的,可能没有正确对齐,可能不指向 引用类型的实体,可能是陷阱表示。

    至于将char 缓冲区的地址转换为(struct inotify_event *)&buffer[i] 中的指针,C 允许指针转换本身。尽管这段代码很可能是一个错误。这种转换存在几个问题:

    • buffer[i] 不一定是对齐的,否则就是访问错误。
    • 指针类型不一定与指向的内容具有相同的大小。反之亦然。例如,将 32 位值存储在 64 位指针中是可行的,但反之则不行。这就是为什么uintptr_t 是用于此类转换的唯一安全整数类型。
    • 如果您取消引用此结构指针或其任何成员,这可能是一个严格的别名违规错误。 What is the strict aliasing rule?

    如果文章描述了一个肮脏的黑客,那么,就是这样。肮脏的黑客不是很稳定或便携。否则,如果文章描述了正确的做事方式,那么作者可能对中级 C 编程不是很熟悉。

    【讨论】:

      猜你喜欢
      • 2011-03-21
      • 2018-08-02
      • 1970-01-01
      • 2011-09-04
      • 2020-11-06
      • 2020-05-21
      • 2013-06-28
      • 1970-01-01
      • 2019-09-21
      相关资源
      最近更新 更多