Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Storage - stack and heaps

Ensure you understand the distinction between POD and non-POD types described in the C++ types section before proceeding.

POD types

POD types are just regular Rust types! Store them on the stack, heap, in a Vec, a HashMap, whatever you want.

Non-POD types

Non-POD types can be stored:

  • In a cxx::UniquePtr. This is cxx’s Rust wrapper for std::unique_ptr - so the object is stored in the C++ heap. Most of the time you handle a C++ object from autocxx, it will be stored in one of these.
  • In a Box - so the object is stored on the Rust heap. This has the advantage that there’s no possibility that the object can be NULL.
  • On the Rust stack, using the autocxx::moveit macro.

If in doubt, use cxx::UniquePtr. It’s simple and ergonomic.

See C++ types for a code example showing a type existing on both the stack and the heap.

Whose heap is it anyway?

Specifically cxx::UniquePtr is a binding to std::unique_ptr<T,std::default_delete<T>> which means the object will be deleted using the C++ delete operator. This will respect any overridden operator delete on the type, and similarly, the functions which autocxx provides to construct types should respect overridden operator new. This means: if your C++ type has code to create itself in some special or unusual heap partition, that should work fine.

The class’s own allocator is found by asking for the two signatures a class declaring nothing else gets, operator new(std::size_t) and operator delete(void*); a class which declares only the sized, aligned or destroying overloads is not seen, and its objects are allocated and freed globally.

A type which asks for more alignment than operator new promises - alignas(32) where the default is 16 - reaches the std::align_val_t overloads C++17 added for exactly that, so it is not handed storage it may not live in. Where autocxx cannot pair an allocation with a deallocation it says so at compile time rather than guess: an over-aligned type before C++17, which has no aligned operator new in the language at all, and an over-aligned type whose class declares only one half of the pair. Giving the class an operator new(std::size_t) and an operator delete(void*) of its own settles every one of those cases.