# How mulle_alloca_do_extract Works: When to Use It Instead of mulle_free

> Learn how mulle_alloca_do_extract works and when to use it for memory ownership transfer over mulle_free. Understand its distinct heap memory management benefits.

- Repository: [mulle-c/mulle-allocator](https://github.com/mulle-c/mulle-allocator)
- Tags: internals
- Published: 2026-03-07

---

**Use `mulle_alloca_do_extract` to transfer ownership of memory from a `mulle_alloca_do` block to the surrounding scope, whereas `mulle_free` only releases heap memory you already own.**

The `mulle_alloca_do_extract` macro in the **mulle-c/mulle-allocator** repository provides a safe mechanism to extract heap-allocated buffers from temporary alloca blocks. Unlike `mulle_free`, which simply deallocates existing heap memory, extraction handles the transition from stack-based temporary storage to persistent heap memory that survives beyond the alloca block scope.

## What Is mulle_alloca_do_extract?

`mulle_alloca_do_extract` is a macro defined in [`src/mulle-alloca.h`](https://github.com/mulle-c/mulle-allocator/blob/main/src/mulle-alloca.h) that extracts the allocated buffer from a `mulle_alloca_do` block and transfers ownership to a variable in the outer scope. This is essential when you need to access the allocated data after the alloca block exits.

A `mulle_alloca_do` block allocates a flexible array that lives on the stack while the requested size remains small, automatically falling back to heap allocation via `mulle_malloc` when the size exceeds the stack limit. The block normally frees the buffer automatically upon exit, but `mulle_alloca_do_extract` intercepts this process to preserve the data.

## How mulle_alloca_do_extract Works

The extraction macro performs four critical operations to safely transition memory ownership:

### Stack Detection and Heap Fallback

First, `mulle_alloca_do_extract` detects whether the variable `name` still points to the temporary stack buffer (internally stored in `name__storage`). If the buffer resides on the stack, the macro allocates a fresh heap block of the same size using `mulle_malloc` and copies the stack contents into it.

### Ownership Transfer and Nulling

The macro then assigns the resulting heap pointer to the `receiver` variable supplied by the caller. Finally, it nulls the original `name` variable so that the automatic cleanup logic inside `mulle_alloca_do` will not attempt to free the memory again.

In [`src/mulle-alloca.h`](https://github.com/mulle-c/mulle-allocator/blob/main/src/mulle-alloca.h) (lines 39-52), this logic ensures that after extraction, the alloca block exits cleanly without touching the transferred memory.

## mulle_alloca_do_extract vs mulle_free

Understanding the distinction between these two operations prevents undefined behavior and memory leaks.

- **`mulle_alloca_do_extract(name, receiver)`**: Transfers ownership from a `mulle_alloca_do` block to the caller. Handles both stack-to-heap copying and simple pointer transfer for already-heap-allocated buffers. Defined in [`src/mulle-alloca.h`](https://github.com/mulle-c/mulle-allocator/blob/main/src/mulle-alloca.h).

- **`mulle_free(pointer)`**: An inline wrapper around `_mulle_allocator_free` defined in [`src/mulle-allocator.h`](https://github.com/mulle-c/mulle-allocator/blob/main/src/mulle-allocator.h) (lines 47-49). It releases a heap block that already belongs to the caller but performs no stack-buffer handling.

**Critical distinction**: Calling `mulle_free` on a pointer that still references the temporary stack buffer created by `mulle_alloca_do` invokes undefined behavior, as stack memory is not heap-allocated.

| Situation | Use `mulle_alloca_do_extract` | Use `mulle_free` |
|-----------|--------------------------------|-------------------|
| Allocating with `mulle_alloca_do` and needing data after the block ends (e.g., returning from a function) | ✅ Extract to a new heap block | ❌ Not applicable (no heap block exists yet) |
| Already own a heap-allocated buffer from `mulle_malloc` and want to release it | ❌ Extraction unnecessary | ✅ Call `mulle_free` |
| Handing an existing heap allocation to another scope without copying | ✅ Transfers ownership and nulls the original | ❌ Block would later free it again |
| Freeing memory obtained from `mulle_calloc` or similar | ❌ Irrelevant | ✅ Use `mulle_free` |

## Practical Code Examples

### Returning Data from a Function

When building a dynamically sized string inside a `mulle_alloca_do` block, use extraction to return the result to the caller:

```c
/* Example: returning a dynamically sized string built inside a mulle_alloca_do block */
char *make_message( const char *fmt, ... )
{
    char *msg;
    mulle_alloca_do( buffer, char, 128 )          // buffer may be stack or heap
    {
        va_list ap;
        va_start( ap, fmt );
        vsnprintf( buffer, (size_t)buffer__count, fmt, ap );
        va_end( ap );

        /* Need the string after the block – extract it */
        mulle_alloca_do_extract( buffer, msg ); // msg now points to heap memory
    }                                            // automatic free does nothing (buffer == NULL)
    return msg;                                 // caller must later mulle_free(msg)
}

/* Caller side */
int main(void)
{
    char *s = make_message( "Hello %s!", "world" );
    puts( s );
    mulle_free( s );            // ordinary heap free
    return 0;
}

```

### Transferring Ownership to Another API

When the allocation is already on the heap (size exceeded the stack limit), extraction simply transfers the pointer without copying:

```c
/* Example: handing a heap-allocated buffer to another API without copying */
void process_data( void *data, size_t size );

void use_alloca_and_pass( size_t needed )
{
    void *tmp;
    mulle_alloca_do( tmp, void, needed )
    {
        /* Fill the buffer … */

        /* The allocation is already on the heap (size > stack limit) */
        mulle_alloca_do_extract( tmp, tmp );  // just transfers ownership
    }   // automatic free does nothing because tmp == NULL

    process_data( tmp, needed );   // tmp now owned by the callee
    /* callee must eventually call mulle_free(tmp) */
}

```

## Summary

- **`mulle_alloca_do_extract`** safely transitions memory from `mulle_alloca_do` blocks to persistent heap storage, handling both stack-to-heap copying and direct ownership transfer.
- The macro nulls the original variable to prevent double-free errors when the alloca block exits.
- **`mulle_free`** only releases heap memory already owned by the caller and must never be used on temporary stack buffers from alloca blocks.
- Both macros are defined in the mulle-c/mulle-allocator repository: `mulle_alloca_do_extract` in [`src/mulle-alloca.h`](https://github.com/mulle-c/mulle-allocator/blob/main/src/mulle-alloca.h) (lines 39-52) and `mulle_free` in [`src/mulle-allocator.h`](https://github.com/mulle-c/mulle-allocator/blob/main/src/mulle-allocator.h) (lines 47-49).

## Frequently Asked Questions

### What is the difference between mulle_alloca_do_extract and mulle_free?

`mulle_alloca_do_extract` transfers ownership of memory from a `mulle_alloca_do` block to the surrounding scope, copying stack data to the heap if necessary. `mulle_free` simply deallocates heap memory that the caller already owns, with no stack-buffer handling or copying logic.

### Can I use mulle_free on memory allocated with mulle_alloca_do?

No. Calling `mulle_free` on a pointer that references the temporary stack buffer created by `mulle_alloca_do` invokes undefined behavior because the memory is not heap-allocated. Always use `mulle_alloca_do_extract` to transition the data to the heap first, then use `mulle_free` later on the extracted pointer.

### Does mulle_alloca_do_extract copy data when extracting?

Only if the buffer currently resides on the stack. If `mulle_alloca_do` allocated the buffer on the heap due to size limits, `mulle_alloca_do_extract` simply assigns the pointer to the receiver and nulls the original without copying data. If the buffer is on the stack, the macro allocates new heap memory and copies the contents.

### Who owns the memory after calling mulle_alloca_do_extract?

After extraction, the receiver variable specified in the macro call owns the heap memory. The original alloca variable is nulled, so the automatic cleanup in the `mulle_alloca_do` block does nothing. The caller is responsible for eventually calling `mulle_free` on the extracted pointer to prevent memory leaks.