【问题标题】:Is buffer valid when the builder is destroyed?构建器被销毁时缓冲区是否有效?
【发布时间】:2019-04-10 09:17:41
【问题描述】:

我正在使用 flatbuffers 序列化对象以通过网络传输,问题是在 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);

我对@9​​87654323@ 的使用是有效的内存缓冲区吗?谢谢。

【问题讨论】:

    标签: c++ serialization flatbuffers


    【解决方案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,但是你需要处理释放内存的事实。由你决定。

    【讨论】:

      【解决方案2】:

      您对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 将拥有底层缓冲内存,并在调用其析构函数后释放它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-30
        • 2011-02-23
        • 2017-07-07
        • 1970-01-01
        • 1970-01-01
        • 2016-07-16
        • 2018-08-28
        • 2021-12-08
        相关资源
        最近更新 更多