1

问题陈述:用户提供了一些我必须存储在结构中的数据。我收到的这些数据采用数据结构,允许用户向其中动态添加数据。

要求: 我需要一种将这些数据连续存储在结构“内部”的方法。

例如。假设用户可以传递我必须存储的字符串。所以我写了这样的东西:

void pushData( string userData )
{
    struct 
    {
       string junk;
    } data;

    data.junk = userData;
}

问题:当我进行这种存储时,实际数据并没有真正存储在结构“内部”,因为字符串不是 POD。当我收到向量或列表时,也会出现类似的问题。

然后我可以做这样的事情:

void pushData( string userData )
{
    struct 
    {
       char junk[100];
    } data;    

    // Copy userdata into array junk
}

这将数据存储在结构“内部”,但是,我不能对用户可以提供的字符串大小设置上限。

有人可以提出一些方法吗?

PS:我读过一些关于可序列化的东西,但如果它对我的情况有帮助,我就不能真正清楚地弄清楚。如果这是前进的道路,有人可以给出如何进行的想法吗?


编辑 :

  1. 不,这不是家庭作业。
  2. 我编写了一个实现,它可以通过消息队列传递这种结构。它适用于 POD,但我需要扩展它以传递动态数据。

这是消息队列获取数据的方式:

一世。给它一个指针并告诉它应该读取和传输数据的大小。

ii. 对于普通的旧数据类型,数据存储在结构内,我可以轻松地将这个结构的指针传递给消息队列给其他进程。

iii. 但是在向量/字符串/列表等情况下,实际数据不在结构内部,因此如果我传递这个结构的指针,消息队列不会真正传递实际数据,而是将存储在内部的指针这种结构。

你可以看到这个这个。我正在尝试实现类似的目标。

4

4 回答 4

3
void pushData( string userData )
{
    struct Data
    {
       char junk[1];
    };

    struct Data* data = malloc(userData.size() + 1);
    memcpy(data->junk, userData.data(), userData.size());
    data->junk[userData.size()] = '\0'; // assuming you want null termination
}

这里我们使用长度为 1 的数组,但我们使用 malloc 分配结构,因此它实际上可以具有我们想要的任何大小。

于 2013-03-07T05:11:24.237 回答
1

表面上你有一些相当人为的约束,但要回答这个问题:对于一个struct包含可变数量的数据的单一是不可能的......你最接近的是让最后一个成员说char [1],把这样一个结构放在一个可变大小的堆区域的开始,并使用不检查数组索引来访问超出该字符的内存这一事实。要了解此技术,请参阅http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html(或 John Zwinck 刚刚发布的答案)

另一种方法是 eg template <size_t N> struct X { char data_[size]; };,但是每个实例化都将是一个单独的结构类型,并且您不能在运行时预先实例化您可能想要的每个大小(假设您已经说过您不想要上限)。即使可以,随着数据的增长编写处理不同实例化的代码也将是一场噩梦,正如代码膨胀所导致的那样。

在一个地方有一个结构,一个字符串成员在另一个地方有数据,几乎总是比上面的hackery更可取。

采取一个希望不是那么疯狂的猜测,我假设您的兴趣是基于起始地址和大小序列化对象,在一些通用的二进制块读/写中......?如果是这样,即使您的目标得到满足,这仍然是个问题,因为您需要从某个地方找出当前的数据大小。编写包含堆上可变长度数据的特定于结构的序列化例程更有希望。

于 2013-03-07T05:14:39.693 回答
0

简单的解决方案:估计数据的最大大小(例如 1000),以防止在 pushData 多次调用时发生内存泄漏(如果释放内存和 malloc 新大小内存 -> 片段内存)。

#define MAX_SIZE 1000
void pushData( string userData )
{
 struct Data
 {
   char junk[MAX_SIZE];
 };


memcpy(data->junk, userData.data(), userData.size());
data->junk[userData.size()] = '\0'; // assuming you want null termination
}
于 2013-03-07T05:45:26.117 回答
0

正如 John Zwinck 所提到的......您可以使用动态内存分配来解决您的问题。

void pushData( string userData )
{
    struct Data
    {
       char *junk;
    };

    struct Data *d = calloc(sizeof(struct data), 1);
    d->junk = malloc(strlen(userData)+1);
    strcpy(d->junk, userdata);
}
于 2013-03-07T05:48:47.243 回答