问题陈述:用户提供了一些我必须存储在结构中的数据。我收到的这些数据来自一个数据结构,允许用户动态地向其添加数据。
要求:我需要一种方法将此数据'保存在结构中,连续。
例如。假设用户可以传递我必须存储的字符串。所以我写了这样的话:
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
}
这个存储数据'里面'的结构,但是,我不能把用户可以提供的字符串大小设置上限。
有人可以建议一些方法吗?
P.S。 :我读过一些关于可串行化的内容,但是如果它对我的案例有帮助的话,那么就无法清楚地说出来。如果是前进的方式,有人可以提出如何继续进行的建议吗?
编辑:
答案 0 :(得分: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分配结构,因此它实际上可以有我们想要的任何大小。
答案 1 :(得分:1)
你表面上有一些相当人为的约束,但回答这个问题:因为单个struct
包含可变数量的数据是不可能的......你最接近的就是让最后的成员成为说char [1]
,将这样的结构放在可变大小的堆区域的开头,并使用不检查数组索引来访问超出该字符的内存的事实。要了解此技术,请参阅http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html(或John Zwinck刚刚发布的答案)
另一种方法是例如template <size_t N> struct X { char data_[size]; };
,但每个实例化都是一个单独的结构类型,并且你无法在运行时预先实例化你想要的每个大小(假设你已经说过你不想要一个上限)。即使你可以,编写处理不同实例化的代码随着数据的增长也会变得噩梦,就像代码膨胀一样。
将一个结构放在一个地方,其中一个字符串成员在另一个地方有数据,这几乎总是比上面的hackery更好。
采取一种希望不是那么疯狂的猜测,我假设你的兴趣在于根据起始地址和大小来序列化对象,在一些通用的二进制块中读/写......?如果是这样,即使你的目标得到满足,这仍然是有问题的,因为你需要从某个地方找出当前的数据大小。编写在堆上包含可变长度数据的特定于结构的序列化例程更有希望。
答案 2 :(得分:0)
简单解决方案:估计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
}
答案 3 :(得分: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);
}