gpt4 book ai didi

c - 获取包含动态分配内存的结构的大小

转载 作者:太空宇宙 更新时间:2023-11-04 01:34:32 25 4
gpt4 key购买 nike

我想为一个缓冲区分配内存,将来通过 memcpy 包含一个结构,该结构包含一个指针,该指针之前已动态分配内存。

也就是说,我有一个结构

struct test_struct {
int num;
char *values;
};

其中 test_struct.values 包含 num 个长度为 LENGTH 的字符串。我知道我无法获得已分配指针的内存大小,所以我只是通过 num 跟踪它。获取此结构大小的最简单/最干净的方法是什么?

我能想出的唯一解决办法是类似

buf = malloc(sizeof(test_struct) + (num * LENGTH));

但我对这种低级内存管理不熟悉,所以可能会有更好的东西。

最佳答案

如果你想 memcpy 两个结构,那么它们中的内存必须是连续的。但是您必须事先确定 num

struct test_struct {
int num;
char ** values;
} * TestStruct;

int _num = 0;

// find _num

TestStruct = malloc (sizeof (struct test_struct) + (sizeof(char*) * _num) + (LENGTH * _num));

TestStruct->num = _num;
TestStruct->values = &TestStruct + sizeof (struct test_struct);

for (int i = 0; i < _num; i++){
TestStruct->values[i] = &TestStruct + sizeof (struct test_struct) + (i * LENGTH);
}

我将 char * 更改为 char ** 的原因是因为使用 char * 在第一个之后访问字符串变得更加困难(我假设它们以 null 终止)。此外,在调用 memcpy 之后,您必须更新新结构中的所有字符串指针。

对于 memcpy 你会这样做:

memcpy (buf, TestStruct->values[0], LENGTH * TestStruct->num);

但是在 buf 中,您只会看到第一个字符串(除非您的字符串不是以 null 结尾的)。您必须在每个空终止字符之后递增指针,直到您知道使用 num 到达缓冲区的末尾。


现在我对您请求的上下文有了更多的了解,请考虑以下事项。

如果您使用的是 UDP 数据包,您应该在一个数据包中发送数据,以便数据按您期望的顺序到达。当发送多个数据包时,它可能会乱序到达。 因此,您需要确保数据的大小 <= 512 字节 - 这是 UDP 数据包的最大大小。 此外,您需要确保所有数据都是连续的内存。我假设您的数据已经存在于您在此示例中提供的结构中:

// this function puts the struct in contiguous memory

int PrepareBuffer (struct test_struct TestStruct, char ** buffer){

char * cast = (char *) &TestStruct->num;

* buffer = malloc ((TestStruct->num * LENGTH) + sizeof (int));

for (int i = 0; i < sizeof (int); i++) *buffer[i] = cast[i];

for (int i = 0; i < (TestStruct->num * LENGTH); i++) *buffer[i + sizeof (int)] = TestStruct->values[i];
return 0;
}

您必须在接收端实现另一个函数,将缓冲区映射到 struct test_struct。此外,为清楚起见,我省略了错误检查。在分配内存 (它必须是<= 512) 之前,您应该检查数据包的大小。您还应该检查以确保 malloc 返回非空指针。

关于c - 获取包含动态分配内存的结构的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16865580/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com