aligned_array.py
# SPDX-FileCopyrightText: 2026 Jeff Epler
#
# SPDX-License-Identifier: CC0-1.0
import ctypes
_alignment_ever_failed = set()
def aligned_array(object_type, alignment=None):
"""Create an aligned array.
Return an array with `count` elements of type `element_type`.
The first element is aligned to a multiple of `alignment`, or
the size of `element_type` if `alignment` is unspecified.
"""
alignment = alignment or ctypes.alignment(object_type)
mask = alignment - 1
if alignment & mask:
raise ValueError("Alignment must be a power of two")
object_size = ctypes.sizeof(object_type)
if alignment not in _alignment_ever_failed:
obj = object_type()
if ctypes.addressof(obj) & mask == 0:
return obj
_alignment_ever_failed.add(alignment)
del obj
alloc_size = object_size + mask
buffer = (ctypes.c_uint8 * alloc_size)()
misalignment = (alignment - ctypes.addressof(buffer)) & mask
result = object_type.from_buffer(
memoryview(buffer)[misalignment:misalignment+object_size]
)
assert ctypes.addressof(result) & mask == 0
return result
if __name__ == '__main__':
arrays1 = [(ctypes.c_uint8 * 4)() for _ in range(16)]
arrays2 = [aligned_array(ctypes.c_uint8 * 4, 16) for _ in range(16)]
arrays3 = [aligned_array(ctypes.c_uint8 * 4, 256) for _ in range(16)]
print("unaligned")
for a in arrays1: print(f"0x...{ctypes.addressof(a) & 0xff:02x}")
print()
print("16-aligned")
for a in arrays2: print(f"0x...{ctypes.addressof(a) & 0xff:02x}")
print()
print("256-aligned")
for a in arrays3: print(f"0x...{ctypes.addressof(a) & 0xff:02x}")
print(f"{_alignment_ever_failed=}")