diff --git a/gobject/gatomicarray.c b/gobject/gatomicarray.c index 506c666c2..57807f1d7 100644 --- a/gobject/gatomicarray.c +++ b/gobject/gatomicarray.c @@ -76,13 +76,14 @@ freelist_alloc (gsize size, gboolean reuse) } } - real_size = sizeof (gsize) + MAX (size, sizeof (FreeListNode)); + real_size = sizeof (GAtomicArrayMetadata) + MAX (size, sizeof (FreeListNode)); mem = g_slice_alloc (real_size); - mem = ((char *) mem) + sizeof (gsize); + mem = ((char *) mem) + sizeof (GAtomicArrayMetadata); G_ATOMIC_ARRAY_DATA_SIZE (mem) = size; #if ENABLE_VALGRIND - VALGRIND_MALLOCLIKE_BLOCK (mem, real_size - sizeof (gsize), FALSE, FALSE); + VALGRIND_MALLOCLIKE_BLOCK (mem, real_size - sizeof (GAtomicArrayMetadata), + FALSE, FALSE); #endif return mem; diff --git a/gobject/gatomicarray.h b/gobject/gatomicarray.h index f7761cc65..a4fdc0103 100644 --- a/gobject/gatomicarray.h +++ b/gobject/gatomicarray.h @@ -27,7 +27,16 @@ G_BEGIN_DECLS -#define G_ATOMIC_ARRAY_DATA_SIZE(mem) (*((gsize *) (mem) - 1)) +typedef union _GAtomicArrayMetadata +{ + gsize size; + /* We have to ensure that the memory location is sufficiently aligned to + * store any object. With C11 this would be max_align_t, but in practise + * gpointer is sufficient for all known architectures. We could change + * this to `_Alignas(max_align_t) char pad` once we depend on C11. */ + gpointer _alignment_padding; +} GAtomicArrayMetadata; +#define G_ATOMIC_ARRAY_DATA_SIZE(mem) (((GAtomicArrayMetadata *) (mem) - 1)->size) typedef struct _GAtomicArray GAtomicArray; struct _GAtomicArray {