我有以下结构:
struct foo
{
int a;
char b;
};它被存储到内存中,指向它的指针可以是非对齐的(奇数地址)。
这安全吗?:
const struct foo a = *((struct foo*)char_ptr); 我很担心,因为源结构的整数成员可以是奇数地址。在某些系统中,从奇数加法中读取(多字节)整数会引起问题。
编辑:为了避免对const的使用进行非主题评论,我从代码中删除了一个const。(我从不将const指针转换为非const指针,即使在这种情况下,它不应该引起任何问题)
和更多的是关于上下文的问题:这种结构是协议框架的一部分。它可以在框架内的任何偏移量中。在实际代码中,结构具有__attribute__((packed))属性。但这可能改变不了答案?
无论如何,我可以用memcopy和non a来解决这个问题。但我想使用测试,因为它似乎是更优雅的方式(如果它是安全的)。
发布于 2012-12-05 14:30:00
不,这是不安全的,除非您知道指针具有结构所需的对齐方式。
下面是一些方法来了解指针是否具有必要的对齐方式:
malloc)的结果,它保证返回的地址被适当地分配给任何使用( malloc确实保证)。uintptr_t并测试其对齐方式。如果不知道指针具有必要的对齐方式,则不应通过转换的指针访问结构。相反,您可以定义一个新结构,并使用memcpy从指针到字符复制到新结构中。
发布于 2012-12-05 12:22:44
见数据结构填充。在大多数系统上,结构将是对齐的&内部成员地址将对齐它们各自的大小,而malloc‘’ing本身。
如果您手动创建一个内存池&使用其中的某个部分来存储您的struct对象,那么编译器将不能保证您对齐,但是如果您使用malloc来创建struct对象,通常会让编译器头疼的是给出对齐的地址,如果需要的话在struct元素之间填充。
发布于 2012-12-05 12:35:17
如果您从指向数据的指针不一定对齐的源获取数据,则唯一安全的操作是memcpy,并希望您的编译器不是“聪明”的,并假装错误指针实际上是对齐的,并且可以优化memcpy ( gcc的几个老版本都有这个bug,要求您编写一个自定义memcpy函数,这个函数不称为memcpy)。取决于您的体系结构,您可以通过不正确的对齐访问来逃避,但它几乎肯定会慢一些,有时甚至会通过内核陷阱进行模拟。
旁白:这通常是操作系统中网络栈中的一个问题,因为以太网报头的奇数大小使IP报头不对齐,如果硬件无法对接收到的数据包(一些DMA引擎只能在4字节边界上写入数据),则需要在软件中再次复制整个报头(或整个数据包)。
https://stackoverflow.com/questions/13723039
复制相似问题