【发布时间】:2014-07-07 01:23:16
【问题描述】:
我有一个函数,它接收分配在堆上的未知类型的数据,我想将它复制到数组中的特定位置。问题是这个函数不能访问数据的类型;只是它的地址和大小。
这是函数可以访问的信息:
unsigned int count; /* length of the array */
unsigned int pos; /* index in the array */
void *data; /* source data */
size_t elemsize; /* sizeof data type */
void *array = malloc(elemcount * elemsize);
我已经达到的解决方案是使用 memcpy 并将数组转换为 char* 以便能够在字节级别上对其进行寻址。
memcpy((char*) array + elemsize * pos, (char*) data, elemsize);
但是,我了解到在某些架构中使用带有未对齐指针的 memcpy 时可能出现的问题。
将源数据转换为 char* 是否会使此操作安全?
在任何情况下,通过将数组转换为 char* 来寻址数组(即sizeof(char) != 1 的任何系统)或以这种方式使用 memcpy 可能会导致问题?
【问题讨论】:
-
你不能不小心尝试在未对齐的数据上使用
memcpy(),因为它的参数有最低对齐要求,也就是_Alignas(char)。只有第一次转换是必需的,因为void*上的指针算术是编译错误。第二个是多余的。 -
我添加了第二个演员表,因为我读到了一些关于 ARM Compilers handle memcpy 的信息。
-
代码对
malloc()的调用为array返回了一个对齐良好的指针。对于大小为elemsize的所有类型,array已正确对齐。memcpy()在指针上工作,就好像它们是char *- 在这里很好地使用(char*) array + elemsize * pos没有问题。查看 ARM 链接,发现它推荐char *cast。根据 C 规范,还没有看到为什么需要强制转换。 -
@JoãoPinheiro 有趣的链接。但是,这里的链接似乎讨论了从指针类型推断对齐 - 也就是说,如果您出于某种原因执行
int *foo = array之类的操作,那么它将假定 4 字节对齐。在这种情况下不适用 -
@chux
A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned57) for the pointed-to type, the behavior is undefined.(6.3.2.3) :)
标签: c arrays memory memcpy memory-alignment