然后在C中取消引用指针

在C中使用char缓冲区时,有时一次处理int数据块会更有用,也更有效。 为此,我可以将我的char *转换为int *并使用该指针代替。 但是,我并不完全相信这种方式与我认为的方式相同。

例如,假设我有char *data*(int32_t *)data = -1总是覆盖字节data[0]data[1]data[2]data[3]而没有其他字节?

扩展我的评论。

这里有两个主要问题:

  • 它违反了严格别名 。
  • 你可能会破坏对齐。

违反严格别名是技术上未定义的行为 。 您可以使用char*为任何数据类型设置别名,但不能反过来。

您可以在GCC上解决f[no-]strict-aliasing问题。


另一个问题是对齐。 char指针可能未正确对齐。 如果硬件不支持未对齐访问,则访问未对齐的数据可能会导致性能下降甚至硬件exception。


如果性能不是问题,那么完全certificate的方法是将memcpy()传递给int数组缓冲区。

解决了这两个问题后,您的示例包括:

 *(int32_t *)data = -1 

如果sizeof(int32_t) == 4 ,则覆盖data[0]data[1]data[2]data[3]应该按预期工作。 只要注意字节顺序……

这是技术上未定义的行为,标准对这样的别名指针的结果保持沉默。 标准学者会说,以这种方式调用未定义的行为可能导致从损坏的数据到系统崩溃到Ragnarok的任何事情。

实际上,这取决于您的硬件。 大多数现代系统(例如x86,x64,PPC,MIPS,ARM)以您描述的方式处理字大小的写入,除了写入未对齐的地址将导致崩溃。 此外,这是endianness发挥作用; 在一个小端系统上

 char foo[4]; *((uint_32*)(foo)) = 0x01020304; // the following are now true: foo[0] == 0x04; foo[1] == 0x03; foo[2] == 0x02; foo[3] == 0x01; 

简短的回答是,除非您确切知道程序运行的硬件,否则这是不安全的。

如果您确实控制了编译的硬件,那么您可以预测编译器将执行的操作; 我已经使用这个技巧来加速嵌入式系统上字节数组的打包。

不,不一定。 如果数据未正确对齐,则可能根本不起作用。 假设它正确对齐,它可能会覆盖下一个sizeof(int)字节,而不是其他任何东西,但我不确定即使那么多也完全可以保证。