此reinterpret_cast崩溃的原因

时间:2015-12-11 07:55:50

标签: c++ crash strict-aliasing

背景:我使用二进制数据工作很多,而且我经常需要使用原始指针。我也经常需要大小,以便我可以检查我是否读取/写出边界(合理,对吧?)。现在我试图为包含底层数据大小的指针创建一个语法糖类,以便我可以简化函数声明。

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

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]);

上面的程序如评论中所述崩溃。 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_cast不是char*而是uint32_t*uint32_t*和编译器并不关心-fno-strict-aliasing {1}}最初指向。
  2. 但即使我使用-fstrict-aliasingdatePicker.addShowRangeHandler(new ShowRangeHandler<Date>() { @Override public void onShowRange(ShowRangeEvent<Date> event) { Date today = new Date(); Date date = new Date(event.getStart().getTime()); while (date.before(event.getEnd())) { if (date.after(today) && datePicker.isDateVisible(date)) { datePicker.setTransientEnabledOnDates(false, date); } CalendarUtil.addDaysToDate(date, 1); } } }); ,程序也会崩溃...(我在GNU / Linux下使用g ++ 5.2.0编译程序。)
  3. 有人可以告诉我哪里出错,我该如何纠正这个问题?

1 个答案:

答案 0 :(得分:1)

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

试图访问地址1234,这不起作用。