C 基于内存对齐将字节数组强制转换为int是否安全?
我最近想将一个4字节数组的内容分配到一个4字节变量中,该变量带有字节移位和逻辑OR 我想检查是否直接将数组转换为int*并获取值有效。我写了一个小测试程序:C 基于内存对齐将字节数组强制转换为int是否安全?,c,arrays,C,Arrays,我最近想将一个4字节数组的内容分配到一个4字节变量中,该变量带有字节移位和逻辑OR 我想检查是否直接将数组转换为int*并获取值有效。我写了一个小测试程序: int main(int argc,char**argv){ int out=0; [4]中的字符={0xFF,0xFF,0xFF,0xFF}; char*in2=NULL; printf(“out=%d\n”,out); out=(int)in[0] 但是我担心内存对齐和这个方法的安全性:它安全吗?如果不安全,是因为编译器规范还是某种未定
int main(int argc,char**argv){
int out=0;
[4]中的字符={0xFF,0xFF,0xFF,0xFF};
char*in2=NULL;
printf(“out=%d\n”,out);
out=(int)in[0]
但是我担心内存对齐和这个方法的安全性:它安全吗?如果不安全,是因为编译器规范还是某种未定义的行为
不,这不安全:
out = *((int*)in);
是未定义的行为,它违反了C别名规则,可能会执行未对齐的访问。memcpy有什么问题吗?int
也有系统的尾端问题。如果int
是32位长且char
没有签名,(int)in[0]@MikeCAT不正确。24左移位在32位整数内。请使用移位/或,但不要使用char
数组!char可以是有符号的或无符号的。在这里一般不要使用有符号整数。通常,请使用stdint.h`typesuint8\t
/uint32\t
。如果最终需要有符号整数,请将结果强制转换为int32\u t
。它不仅具有正确的宽度(对于char
或int
不保证宽度正确),但也保证使用2s补码。谢谢,我搜索了关于别名规则的内容,发现这个主题添加了一些关于它的详细信息:@BenjaminDebotté总结一下,别名规则说只能通过对象自己的类型、其有符号/无符号变体类型或通过字符类型访问对象。除了对齐问题,还可以运行字节排序问题。你的代码假设大端排序,而今天大多数桌面处理器使用小端排序。这个答案是正确的(我刚刚写了相同的一个)。解决此问题的最佳方法是使用memcpy
,大多数编译器都会将其优化为一个简单的加载。另一个问题是,您假设int
为4字节,这在C标准中没有任何保证。最好让out
为uint32\u t
类型,并且执行类似于memcpy(out,in,sizeof(*out))
的操作。当然,正如前面的评论所指出的那样,您将遇到endianness问题。