获取包含动态分配内存的struct的大小

时间:2013-05-31 20:36:17

标签: c memory-management

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

也就是说,我有一个结构

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

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

我能想出的唯一解决方案就是

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

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

3 个答案:

答案 0 :(得分:4)

如果你想记忆两个结构,那么它们中的内存必须是连续的。但您必须事先确定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 *后第一次访问字符串变得更难(我假设它们是空终止的)。此外,在调用memcpy之后,必须更新新结构中的所有字符串指针。

要记住你会这样做:

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

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


现在我了解了您的请求的更多内容,请考虑以下内容。

如果您正在使用UDP数据包,则应将数据发送到一个数据包中,以便按预期顺序到达。当发送多个数据包时,它可能无序到达。 因此,您需要确保数据的大小是&lt; = 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的函数。另外,为了清楚起见,我省略了错误检查。在分配内存(它必须是&lt; = 512)之前,你应该检查数据包的大小。您还应该检查以确保malloc返回一个非空指针。

答案 1 :(得分:0)

你应该只需要分配4个字节(对于32位linux上的整数)和4个字节用于char *(32位.64为8)。

你真正问的是,我怎么知道需要分配给char * value所指向区域的内存量。你在你正在做的事情中弄明白这一点。然后将值设置为buf的位置。如果你有多个字符串,那么有一个评论打击我,这是正确的方法,你不想只是将它们全部塞在那个区域,并且必须弄清楚哪个是你自己。

答案 2 :(得分:0)

我假设您要为结构和值指向的缓冲区分配内存。如果是这样,这是正确的。要指向额外的空格,请buf->values = buf + 1;(假设您将buf声明为struct test_struct buf;