我正在使用平面缓冲区对对象进行序列化以通过网络传输,问题是FlatBufferBuild
超出范围后,缓冲区是否仍然有效,例如:
char* GetBuffer(...size_t &size) {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::Offset<MyStruct> data = CreateMyStruct(fbb, ...);
FinishMyStructBuffer(fbb, data);
size = fbb.GetSize();
return fbb.GetBufferPointer();
}
size_t size;
char* mybuf = GetBuffer(..., size);
do(mybuf, size);
我使用mybuf
有效的内存缓冲区吗?谢谢。
答案 0 :(得分:1)
您对mybuf
的使用无效,这将导致不确定的行为,因为FlatBufferBuilder
在调用其析构函数时会破坏内部缓冲区。我建议使用DetachedBuffer
如下:
flatbuffers::DetachedBuffer GetBuffer(...) {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::Offset<MyStruct> data = CreateMyStruct(fbb, ...);
FinishMyStructBuffer(fbb, data);
return fbb.Release();
}
flatbuffers::DetachedBuffer mybuf = GetBuffer(...);
do(mybuf);
请注意,DetachedBuffer
将拥有底层的缓冲存储器,并在调用析构函数后将其释放。
答案 1 :(得分:1)
FlatBufferBuilder
类将自定义类用作保存数据的基础数组。该类本身称为flatbuffers::vector_downward
,文档说明:
这是std :: vector功能的最小复制,除了从高地址到低地址的增长外。
该类遵循RAII的原则,因此析构函数将处理该作业以释放分配的数据。
~vector_downward() {
clear_buffer();
clear_allocator();
}
因此,基本上,您要访问的是离开函数范围时已取消分配的内存。
现在有很多替代方案可以解决此问题。我将亲自避免在函数中使用另一个参数,并创建一个自定义生成器。像这样:
struct MyStructBuilder {
char* GetBuffer(..., size_t &size) {
flatbuffers::Offset<MyStruct> data = CreateMyStruct(fbb, ...);
FinishMyStructBuffer(fbb, data);
size = fbb.GetSize();
return fbb.GetBufferPointer();
}
private:
flatbuffers::FlatBufferBuilder fbb;
};
MyStructBuilder builder;
size_t size;
char* mybuf = builder.GetBuffer(..., size);
do(mybuf, size);
或者您可以使用FlatBufferBuilder::Release
,但是您需要处理释放内存的事实。由你决定。