# Memory management and reference counting

Due to the nature of its domain, libcbor will need to work with heap memory. The stateless decoder and encoder doesn’t allocate any memory.

If you have specific requirements, you should consider rolling your own driver for the stateless API.

## Using custom allocator

libcbor gives you with the ability to provide your own implementations of `malloc`, `realloc`, and `free`. This can be useful if you are using a custom allocator throughout your application, or if you want to implement custom policies (e.g. tighter restrictions on the amount of allocated memory).

    cbor_set_allocs(malloc, realloc, free);

void cbor_set_allocs(_cbor_malloc_t custom_malloc, _cbor_realloc_t custom_realloc, _cbor_free_t custom_free)

  Sets the memory management routines to use.

  By default, libcbor will use the standard library `malloc`, `realloc`, and `free`.

  Note

  realloc implementation must correctly support NULL reallocation (see e.g. http://en.cppreference.com/w/c/memory/realloc)

  Warning

  This function modifies the global state and should therefore be used accordingly. Changing the memory handlers while allocated items exist will result in a `free`/`malloc` mismatch. This function is not thread safe with respect to both itself and all the other libcbor functions that work with the heap.

  param custom_malloc:

    malloc implementation

  param custom_realloc:

    realloc implementation

  param custom_free:

    free implementation

## Reference counting

As CBOR items may require complex cleanups at the end of their lifetime, there is a reference counting mechanism in place. This also enables a very simple GC when integrating libcbor into a managed environment. Every item starts its life (by either explicit creation, or as a result of parsing) with reference count set to 1. When the refcount reaches zero, it will be destroyed.

Items containing nested items will be destroyed recursively - the refcount of every nested item will be decreased by one.

The destruction is synchronous and renders any pointers to items with refcount zero invalid immediately after calling `cbor_decref()`.

cbor_item_t *cbor_incref(cbor_item_t *item)

  Increases the item’s reference count by one.

  Constant complexity; items referring to this one or items being referred to are not updated.

  This function can be used to extend reference counting to client code.

  param item:

    Reference to an item

  return:

    The input `item`

void cbor_decref(cbor_item_t **item)

  Decreases the item’s reference count by one, deallocating the item if needed.

  In case the item is deallocated, the reference count of all items this item references will also be cbor_decref ‘ed recursively.

  param item:

    Reference to an item. Will be set to `NULL` if deallocated

void cbor_intermediate_decref(cbor_item_t *item)

  Decreases the item’s reference count by one, deallocating the item if needed.

  Convenience wrapper for cbor_decref when its set-to-null behavior is not needed

  param item:

    Reference to an item

size_t cbor_refcount(const cbor_item_t *item)

  Get the item’s reference count.

  Todo:

    Add some inline examples for reference counting

  Warning

  This does not account for transitive references.

  param item:

    the item

  return:

    the reference count

cbor_item_t *cbor_move(cbor_item_t *item)

  Provides CPP-like move construct.

  Decreases the reference count by one, but does not deallocate the item even if its refcount reaches zero. This is useful for passing intermediate values to functions that increase reference count. Should only be used with functions that `incref` their arguments.

  Warning

  If the item is moved without correctly increasing the reference count afterwards, the memory will be leaked.

  param item:

    Reference to an item

  return:

    the item with reference count decreased by one

cbor_item_t *cbor_copy(cbor_item_t *item)

  Take a deep copy of an item.

  All items this item points to (array and map members, string chunks, tagged items) will be copied recursively using cbor_copy. The new item doesn’t alias or point to any items from the original `item`. All the reference counts in the new structure are set to one.

  param item:

    item to copy

  return:

    Reference to the new item. The item’s reference count is initialized to one.

  return:

    `NULL` if memory allocation fails