如何在动态分配的内存中移动参数?

时间:2019-04-18 20:53:18

标签: c pointers memory-management realloc

我很难理解如何使用内存指针。我有两个指针(名称,地址,optionalInfo)指向先前分配的myMemory。这些字符串的大小可以变化。它们像这样存储在myMemory中:

-------------------------------------------------------------------
| int ID 4Bytes | name 6bytes | adress 8Bytes| optionalInfo 8Bytes|
-------------------------------------------------------------------

让我们说我需要增加或减少名称的大小并进行更改。如何正确使用realloc来不丢失我想要的任何信息?如何在内存中转移参数以释放空间以使用新名称?我需要使用最少的内存。

这是我的结构,禁止对其进行更改。

struct myStruct{
    char* name;
    char* adress;
    char* optionalInfo;
    void* myMemory;
};

编辑:myMemory的大小已知。此结构中的名称,地址和optionalInfo是指向存储在myMemory中的字符串的指针

1 个答案:

答案 0 :(得分:0)

让我们根据这种内存布局来考虑这个问题...

-------------------------------------------------------------------
| int ID 4Bytes | name 6bytes | adress 8Bytes| optionalInfo 8Bytes|
-------------------------------------------------------------------

...忽略了它与struct myStruct以外的myMemory成员的关系。

  

让我们说我需要增加或减少名字的大小,   更改。我如何正确使用realloc来不丢失任何内容   我想要的信息吗?

只要您realloc的大小至少等于已占用数据的大小,重新分配就不会丢失任何数据。也不会相对于块的起始地址移动任何内容。但是请注意,重新分配的块可能与原始块不在同一位置,如果已分配,则原始块将被释放,并且不再可以访问。

  

如何将我在内存中的参数转换为自由   一个新名字的空间?

最明显的工具是memmove()函数。因此,假设您想将标有“名称”的区域的大小从6个字节增加到10个字节,而又不覆盖其他任何数据,则首先需要重新分配:

void *temp = realloc(x.myMemory, old_size + 4);

由于不能保证realloc()会成功,因此除非您确信它确实成功,否则不能更新x.myMemory指针:

if (temp) {  // if temp is non-null

然后,您可以在更大的空间内移动地址和optionalInfo数据,以腾出空间容纳更多名称信息:

    memmove(((char *)temp) + new_offset_of_address_data,
            ((char *)temp) + old_offset_of_address_data,
            combined_size_of_address_and_optionalInfo_data);

需要对类型char *进行强制转换,因为指针算术是根据指向类型的单位定义的,因此根本没有为指向void的指针定义。

不要忘记将新的指针分配给您的结构:

    x.myMemory = temp;
}