This document provides an overview of the tools available to manage memory when using the LLCPP bindings.
LLCPP keeps references to objects using:
fidl::StringView
for a string.fidl::VectorView
for a vector of objects.fidl::ObjectView
for a reference to an object.These are non-owning views that only keep a reference and do not manage the object lifetime. The lifetime of the objects must be managed externally. That means that the referenced objects must outlive the views.
In particular, LLCPP generated types do not own their out-of-line children, as defined by the FIDL wire format.
The FIDL allocator (fidl::FidlAllocator
) can allocate LLCPP objects. It manages the lifetime of the allocated LLCPP objects (it owns the objects). As soon as the allocator is deleted, all the objects it has allocated are deallocated and their destructors are called.
The FIDL allocator is defined in lib/fidl/llcpp/fidl_allocator.h.
The objects are first allocated within a buffer which belongs to the allocator (this is a field of the allocator). The default size of the buffer is 512 bytes. A different size can be selected using fidl::FidlAllocator<size>
.
When this buffer is full, the allocator allocates more buffers on the heap. Each of these buffers is 16 KiB (if it needs to allocate an object bigger, it will use a buffer which fit the bigger size).
The standard patern for using the allocator is:
Example:
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/llcpp/unittests/main.cc" region_tag="tables" adjust_indentation="auto" exclude_regexp="^TEST|^}" %}
In addition to the managed allocation strategies, it is also possible to directly create pointers to memory unowned by FIDL. This is discouraged, as it is easy to accidentally create use-after-free bugs. FromExternal
exists to explicitly mark pointers to FIDL-unowned memory.
To create an ObjectView
from an external object using fidl::ObjectView::FromExternal
.
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/llcpp/unittests/main.cc" region_tag="external-object" adjust_indentation="auto" exclude_regexp="^TEST|^}" %}
To create a VectorView
from an external collection using fidl::VectorView::FromExternal
.
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/llcpp/unittests/main.cc" region_tag="external-vector" adjust_indentation="auto" exclude_regexp="^TEST|^}" %}
To create a StringView
from an external buffer using fidl::StringView::FromExternal
.
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/llcpp/unittests/main.cc" region_tag="external-string" adjust_indentation="auto" exclude_regexp="^TEST|^}" %}
A StringView
can also be created directly from string literals without using FromExternal
.
{%includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/llcpp/unittests/main.cc" region_tag="stringview-assign" adjust_indentation="auto" exclude_regexp="^TEST|^}" %}
Defined in lib/fidl/llcpp/string_view.h
Holds a reference to a variable-length string stored within the buffer. C++ wrapper of fidl_string. Does not own the memory of the contents.
fidl::StringView
may be constructed by supplying the pointer and number of UTF-8 bytes (excluding trailing \0
) separately. Alternatively, one could pass a C++ string literal, or any value that implements [const] char* data()
and size()
. The string view would borrow the contents of the container.
It is memory layout compatible with fidl_string.
Defined in lib/fidl/llcpp/vector_view.h
Holds a reference to a variable-length vector of elements stored within the buffer. C++ wrapper of fidl_vector. Does not own the memory of elements.
fidl::VectorView
may be constructed by supplying the pointer and number of elements separately. Alternatively, one could pass any value that supports std::data
, such as a standard container, or an array. The vector view would borrow the contents of the container.
It is memory layout compatible with fidl_vector.
Defined in lib/fidl/llcpp/array.h
Owns a fixed-length array of elements. Similar to std::array<T, N>
but intended purely for in-place use.
It is memory layout compatible with FIDL arrays, and is standard-layout. The destructor closes handles if applicable e.g. it is an array of handles.