Search code examples
c++protocol-buffersemplace

In protocol buffers how to `placement new` inside an arena?


Basically any object can be created on an arena with google::protobuf::Arena::Create. How is it possible to allocate another object in place of an already allocated one? I tried the following:

class My_stuff{};

int main(){
  google::protobuf::Arena arena;
  My_stuff* ptr = google::protobuf::Arena::Create<My_stuff>(&arena);
  ptr = google::protobuf::Arena::Create<My_stuff>(&arena); /* Does this not duplicate the allocated data? */

  return 0;
}

Does that not duplicate data? In case allocating in the place of the object is not possible, how can an object be deleted from the arena? In case messages it's quite straightorward as the release_message method can be used.


Solution

  • For Messages there is no documented way to be removed from the Arena, however Swap() makes it possible to Replace one message with another.

    For RepeatedFields inside a message according to the docs:

    The following methods are added or have some special behavior when arena allocation is enabled. Otherwise, accessor methods just use the default behavior.

    Bar* release_foo(): Returns the existing submessage instance of the field, if set, or a NULL pointer if not set, releasing ownership of this instance to the caller and clearing the parent message's field. Arena support adds additional copying semantics to maintain the contract that the returned object is always heap-allocated:

    • If the parent message is on an arena, this method will make a copy of the submessage on the heap, clear the field value, and return the copy.
    • If the parent message is on the heap, the method behavior is unchanged.