繁体   English   中英

在“内部”结构中存储动态长度数据

[英]Storing dynamic length data 'inside' structure

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

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

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

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。 但是在vector / string / list等的情况下,实际数据不在结构内部,因此如果我传递这个结构的指针,消息队列将不会真正传递实际数据,而是传递存储在内部的指针这个结构。

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

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分配结构,因此它实际上可以有我们想要的任何大小。

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

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

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

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

简单的解决方案:估计max_size数据(ex 1000),以防止内存泄漏(如果空闲内存和malloc新大小内存 - >片段内存)当pushData多次调用时。

#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
}

正如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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM