https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98798
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> --- #include <memory> using std::size_t; struct alignas(32) Foo { char x; void * operator new[ ] (size_t s, std::align_val_t a) { void* p = aligned_alloc(static_cast<size_t>(a), s); __builtin_printf ("p: %p s: %zu, a: %zu\n", p, s, (size_t)a); return p; } void operator delete[ ] (void *p, size_t s, std::align_val_t a) { __builtin_printf ("p: %p s: %zu, a: %zu\n", p, s, (size_t)a); free(p); } }; int main() { auto p = std::make_unique<Foo[]>(3); __builtin_printf("p: %p\n", p.get()); } For this code clang prints: p: 0x4daacc0 s: 128, a: 32 p: 0x4daace0 p: 0x4daacc0 s: 128, a: 32 Notice that the p.get() pointer is not equal to the value returned by aligned_alloc, because the compiler adds a cookie and then adjusts the pointer. G++ prints: p: 0x4dd2cc0 s: 96, a: 32 p: 0x4dd2cc0 ==1233795== Invalid read of size 8 ==1233795== at 0x40144D: std::enable_if<std::is_convertible<Foo (*) [], Foo (*) []>::value, void>::type std::default_delete<Foo []>::operator()<Foo>(Foo*) const (unique_ptr.h:120) ==1233795== by 0x401328: std::unique_ptr<Foo [], std::default_delete<Foo []> >::~unique_ptr() (unique_ptr.h:612) ==1233795== by 0x4011B9: main (98798.C:25) ==1233795== Address 0x4dd2cb8 is 8 bytes before a block of size 96 alloc'd ==1233795== at 0x483D01C: memalign (vg_replace_malloc.c:907) ==1233795== by 0x401203: Foo::operator new[](unsigned long, std::align_val_t) (98798.C:11) ==1233795== by 0x4012A4: std::_MakeUniq<Foo []>::__array std::make_unique<Foo []>(unsigned long) (unique_ptr.h:968) ==1233795== by 0x40118F: main (98798.C:25) ==1233795== p: 0x4dd2cc0 s: 0, a: 32 There are three problems here. Firstly, the p.get() pointer is the same as that returned by aligned_alloc, meaning there is no array cookie. Secondly, the delete[] expression at unique_ptr.h:120 expects a cookie and so inspects the 8 bytes before the pointer value (which valgrind correctly diagnoses as invalid). Thirdly, the size passed to Foo::operator delete[] is zero. Probably because the 8 bytes before the allocation (where the cookie should be) happen to be zero. This is a G++ bug.