1

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

也就是说,我有一个结构

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

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

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

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

但是我对这种低级内存管理的东西很陌生,所以可能会有更好的东西。

4

3 回答 3

4

如果您想 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 * 在第一个之后访问字符串变得更加困难(我假设它们是空终止的)。此外,在调用 memcpy 之后,您必须更新新结构中的所有字符串指针。

要 memcpy,您可以这样做:

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

但是,在 buf 中,您只会看到第一个字符串(除非您的字符串不是以空值结尾的)。您必须在每个空终止字符之后增加指针,直到您知道,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 返回非空指针。

于 2013-05-31T20:39:55.383 回答
0

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

不过,您真正要问的是,我如何知道需要为 char *value 指向的区域分配多少内存。你在你正在做的事情中弄清楚这一点。然后将 value 设置为 buf 的位置。如果你有多个字符串,有一条评论让我大吃一惊,这是正确的方法,你不想在那个区域把它们全部塞在一起,而必须自己弄清楚哪个是哪个。

于 2013-05-31T20:40:08.237 回答
0

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

于 2013-05-31T20:42:58.317 回答