我正在查看一些代码,如下所示:
void whatDoesThisDo(uint8_t *source)
{
STRUCT_T *pStruct;
memcpy(&pStruct, source, sizeof(STRUCT_T));
// this function does some stuff with struct contents
useStruct(pStruct);
}
该函数的意图是从缓冲区'source'填充结构,然后调用'useStruct'(它根据传递给它的struct的指针内容更新全局)。
我认为代码为堆栈上的指针分配内存(因此指向一些随机位置),memcopy然后从'source'推送字节(覆盖pStruct,现在指向其他位置),useStruct使用pStruct的内容作为struct的指针。
答案 0 :(得分:4)
原始代码:
STRUCT_T *pStruct;
memcpy(&pStruct, source, sizeof(STRUCT_T));
将STRUCT_T
复制到STRUCT_T*
,这是编程错误。
你可能想要的是:
void whatDoesThisDo(uint8_t *source)
{
STRUCT_T Struct; // Allocate a Struct on the stack.
memcpy(&Struct, source, sizeof(STRUCT_T));
// this function does some stuff with struct contents
useStruct(&Struct);
}
假设source
指向STRUCT_T
。
如果source
与STRUCT_T
正确对齐,则此功能可能只是:
void whatDoesThisDo(uint8_t *source)
{
useStruct((STRUCT_T*)source);
}
答案 1 :(得分:0)
目前无效。
如果您希望pStruct
拥有动态存储持续时间,那么您需要自己为目标缓冲区pStruct
分配内存。请使用malloc
。然后使用memcpy(pStruct, source, sizeof(STRUCT_T));
复制结构。请注意,我将pStruct
而不是地址传递给memcpy
。
或者,您可以将pStruct
定义为具有自动存储持续时间;即写
STRUCT_T pStruct;
(可能重命名变量,使其看起来不像指针类型),并使用memcpy(&pStruct, source, sizeof(STRUCT_T));
答案 2 :(得分:0)
该函数的目的是从缓冲区' source'填充结构。
您还没有创建任何要填充的结构。
然后拨打' useStruct' (根据传递给它的struct的指针内容更新全局)。
那部分没问题。
我认为代码为堆栈上的指针分配内存(因此指向一些随机位置),
是。 指针的内存是这里的关键。不是结构的内存。
memcopy然后从' source'中推送字节。 (覆盖pStruct,现在指向其他地方),
是。但是你用结构本身覆盖了指针。指针现在没有任何意义。另外,指针通常比结构小得多,所以你不仅覆盖了指针,还覆盖了一些内存。这是非常糟糕的事情,因为没有人可以告诉谁使用了那个记忆和什么,所以可能有一些重要的东西,你现在已经破坏了你的程序。
和useStruct使用pStruct的内容作为struct的指针。
是的,它使用pStruct的内容作为struct的指针 - 但正如我所说它现在包含结构本身,而不仅仅是一个指针。
您必须将指针视为与其指向的不同类型。例如,我的手指是一个指针,我指着它在自由女神像。你所做的是你将自由女神像的内容复制到手指中。它不合适。你需要的是获得另一个雕像大小的记忆场所,将原始雕像复制到那里,然后你可以用手指将其指向新的雕像。