# Use and define free\_aligned\_sized, aligned\_alloc (and free\_sized)

**URL:** <https://discourse.julialang.org/t/use-and-define-free-aligned-sized-aligned-alloc-and-free-sized/131967>\
**Category:** Internals & Design\
**Created:** [August 30, 2025, 3:35pm UTC](https://discourse.julialang.org/t/use-and-define-free-aligned-sized-aligned-alloc-and-free-sized/131967 "2025-08-30T15:35:15Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [August 30, 2025, 3:35pm UTC](https://discourse.julialang.org/t/use-and-define-free-aligned-sized-aligned-alloc-and-free-sized/131967/1 "2025-08-30T15:35:15Z")

</div>

E.g. for Libc.

Currently Julia uses [`posix_memalign`](https://pubs.opengroup.org/onlinepubs/009604499/functions/posix_memalign.html) (except on Windows) for itself (sometimes) and corresponding `free`, not special free for aligned, as needed on Windows, but we likely should everywhere:

> **[N2699 - Sized Memory Deallocation](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2699.htm)**

> Several heap allocators[1](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2699.htm#fn1) (hereafter, “allocators”) expose as extensions variants of `free` that accept, in addition to the address of the allocation, an additional argument “reminding” the allocator of the size of that allocation. These extensions can reduce deallocation cost by 30%, allow extra security-hardening functionality, and currently ship in several implementations.

Julia bypasses Libc.malloc, has its own pool system which is likely redundant, and is a problem for me (when I tried to test mimalloc).

I’m not sure we would get a speedup or improved safety unless we disable Julia’s pools (that can be a separate decision; and discussion for later). I.e. for most allocations. But there are more allocations in Julia that go straight to malloc, or malloc\_s, or some other Julia wrapper for. I see for thread-local storage, aligned malloc is used, and memset after, so in effect calloc, and I considered changing to calloc. But first of, this is likely not speed-critical (and only done once per thread?) and there’s no corresponding aligned malloc I found out, in the standard…

The problem for free\_aligned\_sized is that it’s only defined in C23, but it needs not be a problem. I was confused at first seeing it only working for aligned\_alloc, and free\_sized only working for other allocations, but in fact a legal implementation for both is just doing regular free.

So for Libc, we could do that, unless Julia is compiled with C23, and we should do that by default, but not have it as a requirement with a fallback for such libc library/allocators. And users of Julia’s Libc library can opt into the new allocators and deallocators gradually.

> <https://stackoverflow.com/questions/23092621/why-is-there-no-aligned-calloc-in-c11>

> <https://github.com/bloomberg/memray/pull/817>
>
> closes #725 
> 
> This commit introduces 2 new functions to add support for \`free\_…sized\` and \`free\_aligned\_sized\` deallocators introduced in c23.
> 
> Tests ensure that \`free\_sized\` and \`free\_aligned\_sized\` are skipped if unavailable otherwise we get a \`FREE\` record recorded for them.

> **[Why does calloc exist? — njs blog](https://vorpus.org/blog/why-does-calloc-exist/)**

FYI:

> **[Memory management library - cppreference.com](https://en.cppreference.com/w/cpp/memory.html)**

[is\_sufficiently\_aligned](https://en.cppreference.com/w/cpp/memory/is_sufficiently_aligned.html) (C++26) checks whether the pointer points to an object whose alignment has at least the given value

> **[std::assume\_aligned - cppreference.com](https://en.cppreference.com/w/cpp/memory/assume_aligned.html)**

> Informs the implementation that the object ptr points to is aligned to at least `N`. The implementation may use this information to generate more efficient code, but it might only make this assumption if the object is accessed via the return value of `assume_aligned`.
> 
> `N` must be a power of 2.

> ### Types for composite class design (since C++26)
> 
> Defined in header `<memory>`  
> [indirect](https://en.cppreference.com/w/cpp/memory/indirect.html)
> 
> (C++26) a wrapper containing dynamically-allocated object with value-like semantics  
> (class template)  
> [polymorphic](https://en.cppreference.com/w/cpp/memory/polymorphic.html)
> 
> (C++26) a polymorphic wrapper containing dynamically-allocated object with value-like semantics  
> (class template)

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [September 1, 2025, 11:01am UTC](https://discourse.julialang.org/t/use-and-define-free-aligned-sized-aligned-alloc-and-free-sized/131967/2 "2025-09-01T11:01:01Z")

</div>

> [@Palli](#):
>
> I see for thread-local storage, aligned malloc is used, and memset after, so in effect calloc, and I considered changing to calloc.

Apart from alignment, there is the issue of on-demand paging: `calloc` can be either malloc+memset, or it can be an `mmap`, at the discretion of your allocator’s internal state.

Often `mmap` and lazy paging is preferable.

However, specifically for thread initialization, laziness is super scary:

Some thread might be in a spinlock critical section when the pagefault hits. And julia spinlocks really spin forever, instead of falling back to a futex after some time. (^this is something we should fix. True spinlocks are almost never the answer, because performance tanks if the thread holding the crit section gets preempted by the OS or pagefaults)
