---
source_path: "api/heap.md"
canonical_url: "https://doc.sensory.com/tnl/7.8/api/heap/"
---

# Memory management

This section describes heap memory management used by the TrulyNatural SDK C language binding.
The Java and Python bindings manage native handles from their language runtimes.

SDK handles ([Session](https://doc.sensory.com/tnl/7.8/api/inference.md#session), [Stream](https://doc.sensory.com/tnl/7.8/api/io.md#stream), [Callback](https://doc.sensory.com/tnl/7.8/api/inference.md#callback)) are [reference-counted](https://doc.sensory.com/tnl/7.8/api/heap.md#reference-counting).
Manage the lifetime of these objects with [retain](https://doc.sensory.com/tnl/7.8/api/heap.md#retain) and [release](https://doc.sensory.com/tnl/7.8/api/heap.md#release).

Objects are created with a reference count of zero. This makes
it cleaner to use a new object as a function argument without having to keep
a handle to it just to be able to release it afterwards.

This library uses a small amount of heap memory to keep track of library-wide
configuration options. You can use [tearDown](https://doc.sensory.com/tnl/7.8/api/heap.md#teardown) to free these allocations.

Python callers do not call [retain](https://doc.sensory.com/tnl/7.8/api/heap.md#retain) or [release](https://doc.sensory.com/tnl/7.8/api/heap.md#release) directly. `Session` and
`Stream` wrappers own their native handles and release them when Python
finalizes the objects; use `with snsr.Session() as s:` or
`with snsr.Stream.from_*(...) as s:` (or explicit `release()`) to free native
resources promptly. [getStream](https://doc.sensory.com/tnl/7.8/api/inference.md#getters) returns a retained `Stream` wrapper, so
the object remains valid after further calls on the same session.

## Best practices

* If you keep a reference to a handle, call [retain](https://doc.sensory.com/tnl/7.8/api/heap.md#retain) on it to increment the reference count.
* Call [release](https://doc.sensory.com/tnl/7.8/api/heap.md#release) before giving up the reference. This will decrease the reference count and
  deallocate the object one the reference count is `<= 0`.
* Functions that take reference-counted objects as arguments must
    * Call [retain](https://doc.sensory.com/tnl/7.8/api/heap.md#retain) on function entry for each of these arguments.
    * Call [release](https://doc.sensory.com/tnl/7.8/api/heap.md#release) on function exit for each of these arguments,
      except for the ones where long-running references were kept.
    * Follow this retain/release procedure even when the function returns an
      error condition, as it allows for convenient function composition
      without memory leaks.

## Reference counting

### release
<!-- tab: c -->

**C/C++**

```c
SNSR_API void
snsrRelease(const void *handle);
```

**Parameters and return value:**

**Input parameter:** `handle`

* A reference-counted object, or `NULL`.

Releases an object reference.

Decrements the reference count on `handle`. If the reference count
drops to zero (or below), this will deallocate `handle`.

When this function returns `handle` will no longer be valid.
Accessing a released `handle` in any way will lead to
[undefined behavior][undefined-behavior].

**Note:**

`handle` must be `NULL`, or a valid reference-counted object
returned by this library, such as [Session](https://doc.sensory.com/tnl/7.8/api/inference.md#session), [Stream](https://doc.sensory.com/tnl/7.8/api/io.md#stream),
or [Callback](https://doc.sensory.com/tnl/7.8/api/inference.md#callback) handle, or a `const char *` returned by [getString](https://doc.sensory.com/tnl/7.8/api/inference.md#getters).

Behavior on any other pointer is undefined and will likely
lead to the process calling `abort()`.

**Also see these related items:** [release](https://doc.sensory.com/tnl/7.8/api/heap.md#release), [Callback](https://doc.sensory.com/tnl/7.8/api/inference.md#callback), [Session](https://doc.sensory.com/tnl/7.8/api/inference.md#session), [Stream](https://doc.sensory.com/tnl/7.8/api/io.md#stream), [getString](https://doc.sensory.com/tnl/7.8/api/inference.md#getters)

<!-- /tab -->

### retain
<!-- tab: c -->

**C/C++**

```c
SNSR_API void
snsrRetain(const void *handle);
```

**Parameters and return value:**

**Input parameter:** `handle`

* A reference-counted object.

Retains a reference to an object.

Increments the reference count on `handle`. The `handle` will remain
valid until you call [release](https://doc.sensory.com/tnl/7.8/api/heap.md#release) on it.

To avoid memory leaks, be sure to match each call to [retain](https://doc.sensory.com/tnl/7.8/api/heap.md#retain) with
exactly one call to [release](https://doc.sensory.com/tnl/7.8/api/heap.md#release).

**Note:**

`handle` must be a valid reference-counted object
returned by this library, such as [Session](https://doc.sensory.com/tnl/7.8/api/inference.md#session), [Stream](https://doc.sensory.com/tnl/7.8/api/io.md#stream),
or [Callback](https://doc.sensory.com/tnl/7.8/api/inference.md#callback) handle, or a `const char *` returned by [getString](https://doc.sensory.com/tnl/7.8/api/inference.md#getters).

Behavior on any other pointer (including `NULL`) is undefined and will likely
lead to the process calling `abort()`.

**Also see these related items:** [release](https://doc.sensory.com/tnl/7.8/api/heap.md#release), [Callback](https://doc.sensory.com/tnl/7.8/api/inference.md#callback), [Session](https://doc.sensory.com/tnl/7.8/api/inference.md#session), [Stream](https://doc.sensory.com/tnl/7.8/api/io.md#stream), [getString](https://doc.sensory.com/tnl/7.8/api/inference.md#getters)

<!-- /tab -->

## Heap allocation

You can replace the standard library heap allocator
used by the TrulyNatural SDK with one of the provided [heap allocators](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators),
or one of your [own design](https://doc.sensory.com/tnl/7.8/api/library-config.md#user-defined-allocator).

The functions in this section provide replacements for `malloc()`, `realloc()`, and `free()`
that use this heap allocator. These are for convenience only,
they're not used or required by the TrulyNatural SDK API.

### malloc
<!-- tab: c -->

**C/C++**

```c
SNSR_API void *
snsrMalloc(size_t size);
```

**Parameters and return value:**

**Input parameter:** `size`

* Number of bytes to allocate on the heap.

**Return value:** * Pointer to the start of a memory block at least `size` bytes long.

Allocate memory with TrulyNatural SDK allocator.

This function works like `malloc()`, but uses this SDK's
dynamic memory allocator instead.

This is provided for convenience only, it is not used or required by the library API.

**Note:**

`snsrMalloc()` will never return `NULL`. A failed memory allocation
results in a library-wide panic. You can provide a custom panic function
with [PANIC_FUNC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_panic_func).

**Also see these related items:** [heap allocators](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators), [free](https://doc.sensory.com/tnl/7.8/api/heap.md#free), [realloc](https://doc.sensory.com/tnl/7.8/api/heap.md#realloc)

<!-- /tab -->

### free
<!-- tab: c -->

**C/C++**

```c
SNSR_API void
snsrFree(void *ptr);
```

**Parameters and return value:**

**Input parameter:** `ptr`

* `NULL`, or an allocation previously returned by [malloc](https://doc.sensory.com/tnl/7.8/api/heap.md#malloc) or [realloc](https://doc.sensory.com/tnl/7.8/api/heap.md#realloc).

Free heap memory allocated on the TrulyNatural SDK heap.

This function works like `free()`, but uses this library's
dynamic memory allocator.

The `ptr` parameter must be `NULL` or be an allocation returned by either `snsrMalloc()` or
`snsrRealloc()`. Any other value will result in undefined behavior.

This is provided for convenience only, it is not used or required by the
library API.

**Also see these related items:** [heap allocators](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators), [malloc](https://doc.sensory.com/tnl/7.8/api/heap.md#malloc), [realloc](https://doc.sensory.com/tnl/7.8/api/heap.md#realloc)

<!-- /tab -->

### realloc
<!-- tab: c -->

**C/C++**

```c
SNSR_API void *
snsrRealloc(void *ptr, size_t size);
```

**Parameters and return value:**

**Input parameter:** `ptr`

* Allocation returned by [malloc](https://doc.sensory.com/tnl/7.8/api/heap.md#malloc) or [realloc](https://doc.sensory.com/tnl/7.8/api/heap.md#realloc), or `NULL`.

**Input parameter:** `size`

* Number of bytes to allocate on the heap.

**Return value:** * Pointer to the start of a memory block at least `size` bytes long.

Resize a heap block allocated on the TrulyNatural SDK heap.

This function works like `realloc()`, but uses this library's
dynamic memory allocator.

The `ptr` parameter must `NULL`, or contain a value returned by `snsrMalloc()` or
`snsrRealloc()`. Any other value will result in undefined behavior.

This is provided for convenience only, it is not used or required by the
library API.

**Note:**

`snsrRealloc()` will never return `NULL`. A failed memory allocation
results in a library-wide panic. You can provide a custom panic function
with [PANIC_FUNC](https://doc.sensory.com/tnl/7.8/api/library-config.md#config_panic_func).

**Also see these related items:** [heap allocators](https://doc.sensory.com/tnl/7.8/api/library-config.md#heap-allocators), [free](https://doc.sensory.com/tnl/7.8/api/heap.md#free), [malloc](https://doc.sensory.com/tnl/7.8/api/heap.md#malloc)

<!-- /tab -->

## Free library resources

### tearDown
<!-- tab: c -->

**C/C++**

```c
SNSR_API SnsrRC
snsrTearDown(void);
```

**Parameters and return value:**

**Return value:** * [OK](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_ok) for success, any other value indicates failure.

Releases library-wide resources.

Resets the TrulyNatural SDK library to the initial defaults and releases
all library-wide resources.

Calling this function is optional. It is most useful to suppress false
positives when tracking down heap leaks with a tool such as [Valgrind][].

**Warning:**

Do **not** call this function unless all SDK handles have been released.
Doing so will lead to [undefined behavior][undefined-behavior].

**Also see these related items:** [config](https://doc.sensory.com/tnl/7.8/api/library-config.md#config)

<!-- /tab -->

<!-- Reference definitions from includes/links.md -->
[undefined-behavior]: https://en.wikipedia.org/wiki/Undefined_behavior "Undefined program behavior"
[Valgrind]: https://en.wikipedia.org/wiki/Valgrind "Valgrind is a programming tool for memory debugging, memory leak detection, and profiling"

<!-- Abbreviation definitions from includes/abbreviations.md -->
*[API]: Application Programming Interface
*[SDK]: Software Development Kit
*[TNL]: TrulyNatural, Sensory's large-vocabulary speech recognition technology
