Действительно ли буфер действителен при разрушении компоновщика? - PullRequest
0 голосов
/ 10 апреля 2019

Я использую плоские буферы для сериализации объектов для передачи по сети, вопрос в том, остается ли буфер действительным после того, как 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 действительный буфер памяти?Спасибо.

Ответы [ 2 ]

1 голос
/ 10 апреля 2019

Класс 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, но вам нужно будет разобраться с фактом освобождения памяти.Тебе решать.

1 голос
/ 10 апреля 2019

Использование 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 будет владеть основной буферной памятью и освободит ее после вызова деструктора.

...