Skip to content

Instantly share code, notes, and snippets.

@MonocleSecurity
Last active February 13, 2026 08:58
Show Gist options
  • Select an option

  • Save MonocleSecurity/923066bf39ce2b673ec8a0a2b2316087 to your computer and use it in GitHub Desktop.

Select an option

Save MonocleSecurity/923066bf39ce2b673ec8a0a2b2316087 to your computer and use it in GitHub Desktop.
Aligned memory allocator for std::unique_ptr
#include <memory>
void* AlignedMalloc(const size_t size, const size_t alignment)
{
const size_t offset = alignment - 1 + sizeof(void*);
void* buffer = malloc(size + offset);
void** ptr = reinterpret_cast<void**>((reinterpret_cast<size_t>(buffer) + offset) & ~(alignment - 1));
ptr[-1] = buffer;
return ptr;
}
void AlignedFree(void* ptr)
{
free((static_cast<void**>(ptr))[-1]);
}
template <class T>
struct DeleteAligned
{
void operator()(T* ptr) const
{
ptr->~T();
#ifdef _WIN32
_aligned_free(ptr);
#else
AlignedFree(ptr);
#endif
}
};
template <class T, class... Args>
std::unique_ptr<T, DeleteAligned<T>> AlignedAlloc(const int alignment, Args... args)
{
#ifdef _WIN32
T* buf = static_cast<T*>(_aligned_malloc(sizeof(T), alignment));
#else
T* buf = static_cast<T*>(AlignedMalloc(sizeof(T), alignment));
#endif
T* ptr = new (buf) T(args...);
return std::unique_ptr<T, DeleteAligned<T>>{ ptr };
}
template <class T>
std::unique_ptr<T[], DeleteAligned<T>> AlignedAllocArray(const int alignment, const int length)
{
#ifdef _WIN32
T* ptr = static_cast<T*>(_aligned_malloc(sizeof(T) * length, alignment));
#else
T* ptr = static_cast<T*>(AlignedMalloc(sizeof(T) * length, alignment));
#endif
return std::unique_ptr<T[], DeleteAligned<T>>(ptr);
}
int main()
{
std::unique_ptr<int, utility::DeleteAligned<int>> ptr = utility::AlignedAlloc<int>(PAGE_SIZE, 5);
std::unique_ptr<uint8_t[], utility::DeleteAligned<uint8_t>> buffer_ = AlignedAllocArray<uint8_t>(PAGE_SIZE, 1024);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment