简体   繁体   English

C:使用memcpy分配结构

[英]C: Allocating structs using memcpy

I am looking at some code somewhat as below: 我正在看一些如下的代码:

void whatDoesThisDo(uint8_t *source)
{
    STRUCT_T *pStruct;
    memcpy(&pStruct, source, sizeof(STRUCT_T));

    // this function does some stuff with struct contents
    useStruct(pStruct);
}

The intention of the function is to populate the struct from buffer 'source' and then call 'useStruct' (which updates a global based on the contents of the pointer to struct passed to it). 该函数的目的是从缓冲区“源”中填充结构,然后调用“ useStruct”(后者将根据传递给它的结构的指针的内容来更新全局变量)。

I think the code allocates memory for the pointer on the stack (so pointing to some random location), memcopy then pushes bytes from 'source' (overwriting pStruct, so that now points somewhere else), and useStruct uses content of pStruct as pointer to struct. 我认为代码为堆栈上的指针分配了内存(因此指向某个随机位置),然后内存复制从“源”中推送字节(覆盖pStruct,因此现在指向其他地方),而useStruct使用pStruct的内容作为指向的指针结构。

The original code: 原始代码:

STRUCT_T *pStruct;
memcpy(&pStruct, source, sizeof(STRUCT_T));

Copies STRUCT_T into STRUCT_T* , which is an programming error. 副本STRUCT_TSTRUCT_T* ,这是一个编程错误。

What you probably want is: 您可能想要的是:

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);
}

That assumes that source points to a STRUCT_T . 假定source指向STRUCT_T

If source is correctly aligned for STRUCT_T , then this function could be just: 如果source是正确的对齐STRUCT_T ,那么这个功能可能只是:

void whatDoesThisDo(uint8_t *source)
{
    useStruct((STRUCT_T*)source);
}   

This will not currently work. 目前无法使用。

If you want pStruct to have dynamic storage duration , then you need to allocate memory for the destination buffer pStruct yourself. 如果希望pStruct具有动态存储持续时间 ,则需要自己为目标缓冲区pStruct分配内存。 Use malloc for that. 为此使用malloc Then use memcpy(pStruct, source, sizeof(STRUCT_T)); 然后使用memcpy(pStruct, source, sizeof(STRUCT_T)); to copy the structure. 复制结构。 Note that I pass pStruct , not an address to memcpy . 请注意,我传递的是pStruct ,而不是memcpy地址

Alternatively, you could define pStruct to have automatic storage duration; 另外,您可以将pStruct定义为具有自动存储时间; ie write 即写

STRUCT_T pStruct;

(perhaps renaming the variable so it doesn't look like a pointer type), and use memcpy(&pStruct, source, sizeof(STRUCT_T)); (也许重命名该变量,使其看起来不像指针类型),并使用memcpy(&pStruct, source, sizeof(STRUCT_T));

The intention of the function is to populate the struct from buffer 'source' 该功能的目的是从缓冲区“源”中填充结构

You haven't created any struct to populate. 您尚未创建任何要填充的结构。

and then call 'useStruct' (which updates a global based on the contents of the pointer to struct passed to it). 然后调用“ useStruct”(它会根据传递给它的struct的指针内容更新全局变量)。

That part is OK. 那部分没问题。

I think the code allocates memory for the pointer on the stack (so pointing to some random location), 我认为代码为堆栈上的指针分配了内存(因此指向某个随机位置),

Yes. 是。 memory for the pointer is the key here. 指针的存储是这里的关键。 Not memory for the struct. 不是该结构的内存。

memcopy then pushes bytes from 'source' (overwriting pStruct, so that now points somewhere else), 然后,内存复制会从“源”中推送字节(覆盖pStruct,因此现在指向其他位置),

Yes. 是。 But you overwrote the pointer with the struct itself. 但是您用结构本身覆盖了指针。 The pointer doesn't make any sense now. 指针现在没有任何意义。 Plus, the pointer is typically much smaller than a struct, so you overwrote not just the pointer, but also some memory after it. 另外,指针通常比结构小得多,因此您不仅要覆盖指针,而且还要覆盖其后的一些内存。 Which is very bad thing, because nobody can tell who used that memory and for what, so there possibly was something important there and you've destabilized your program now. 这是非常糟糕的事情,因为没有人能告诉谁使用了该内存以及用于什么用途,因此那里可能存在重要的事情,并且您现在已经使程序不稳定。

and useStruct uses content of pStruct as pointer to struct. useStruct使用pStruct的内容作为struct的指针。

Yes, it uses content of pStruct as pointer to struct - but as I said it now contains the struct itself, not just a pointer. 是的,它使用pStruct的内容作为struct的指针-但正如我所说的,它现在包含struct本身,而不仅仅是一个指针。

You must treat the pointer as a distinct type than what it points at. 您必须将指针视为不同于其所指向的类型。 Eg my finger is a pointer and I am pointing it at a Statue Of Liberty. 例如,我的手指是指针,而我指的是自由女神像。 What you did is you copied the content of Statue Of Liberty into a finger. 您所做的是将自由女神像的内容复制到一根手指上。 It won't fit. 不适合 What you need is to get another Statue-sized memory place, copy the original Statue there and then you can take a finger and point it into new Statue. 您需要的是再获得一个雕像大小的存储位置,在其中复制原始雕像,然后您可以用一根手指将其指向新雕像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM