我使用扁平缓冲区来序列化要通过网络传输的对象,问题是在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
是否有效内存缓冲区?谢谢。
发布于 2019-04-10 09:58:08
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
,但您需要处理释放内存的问题。由你决定。
发布于 2019-04-10 09:53:27
您对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
将拥有底层缓冲区内存,并在其析构函数被调用时释放它。
https://stackoverflow.com/questions/55608967
复制