我有一个函数接收堆上分配的未知类型的数据,我想将它复制到数组中的特定位置。问题是该功能无法访问数据类型;只是它的地址和大小。
这是该函数可以访问的信息:
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的任何系统来解决数组可能导致问题的情况?
答案 0 :(得分:2)
将源数据转换为char *会使此操作安全吗?
这没什么区别。
是否存在通过将数组转换为char *来解决数组(即任何sizeof(char)!= 1的系统)或以这种方式使用memcpy会导致问题的情况?
没有sizeof(char) != 1
的系统。该标准规定必须为1
。
使用memcpy
从来没有任何问题,只要不超出正在读写的对象的边界,并且目标是可写的,并且对象不会重叠。特别是没有任何对齐问题。
(如果您没有成功构建该对象的有效表示,则在尝试访问复制到的对象时可能会出现问题)。
在某些架构中使用带有未对齐指针的memcpy时,我已经读过可能出现的问题。
要么你误解了你所读的内容,要么就是错误的信息。如果您正在讨论链接ARM文章中的代码:
void example (unsigned int * const unaligned_ptr)
{
如果unaligned_ptr
未正确对齐unsigned int
,则在执行进入函数体之前,行为已经未定义。该页面似乎提供了一种尝试从未定义的行为中恢复的方法。这是一个相当糟糕的想法恕我直言,最好不要首先发起未定义的行为;或检测它然后抛出某种致命异常,以便调试和纠正问题。