【问题标题】:Reason why this reinterpret_cast crashes此 reinterpret_cast 崩溃的原因
【发布时间】:2015-12-11 16:17:22
【问题描述】:

背景:我经常处理二进制数据,而且我经常需要处理原始指针。我也经常需要大小,以便我可以检查我是否读/写了边界(合理,对吗?)。现在我正在尝试为包含基础数据大小的指针创建一个语法糖类,以便我可以简化函数声明。

问题演示 - 我的课程背后的崩溃代码可以简化为:

char *a = (char*) malloc(4); // some underlying data
strncpy(a, "1234", 4); // that is not statically linked so it can be written to

uint32_t *ptr = reinterpret_cast<uint32_t*>(a);

ptr[0] = 1234; // works
reinterpret_cast<int&>(ptr[0]) = 1234; // curiously, this works too
*reinterpret_cast<int*>(ptr[0]) = 1234; // this crashes the program

printf("%d\n", ptr[0]);

上述程序崩溃,如 cmets 中所述。 Valgrind 输出如下:

Invalid write of size 4
   at 0x40064A: main (in /home/rr-/test)
 Address 0x4d2 is not stack'd, malloc'd or (recently) free'd

我怀疑我违反了严格的别名规则,但是:

  1. 我确保使用char* 作为底层结构。很可能,这并不重要,因为我的 reinterpret_casting 不是 char*,而是 uint32_t*,编译器并不关心 uint32_t* 最初指向的内容。
  2. 但即使我使用-fno-strict-aliasing-fstrict-aliasing,程序仍然崩溃...(我在 GNU/Linux 下使用 g++ 5.2.0 编译程序。)

谁能告诉我哪里出错了,我该如何纠正这个问题?

【问题讨论】:

  • 你认为*reinterpret_cast&lt;int*&gt;(ptr[0]) = 1234; 会做什么?
  • 是的,我在上下班途中意识到了这一点。多么愚蠢的错误。

标签: c++ crash strict-aliasing


【解决方案1】:

您刚刚将 1234 存储在 ptr[0] 中。然后将 1234 转换为指针并取消引用它。

尝试访问地址 1234,但不起作用。

【讨论】:

    猜你喜欢
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 2011-12-19
    相关资源
    最近更新 更多