https://gcc.gnu.org/bugzilla/show_bug.cgi?id=8670
--- Comment #22 from Jonathan Wakely <redi at gcc dot gnu.org> --- This bug is still present in the COW std::string, which is still supported even though it's not the default. There are two problems. The first is the one reported by James Kanze, that the string contents need to be aligned to alignof(_CharT) but are currently aligned to 1. The second, stated by Nathan in comment 13, is that the _Rep object needs to be aligned to alignof(_Rep), not 1. The reference count in the _Rep ends up misaligned, and the atomic operations on it are undefined. Here's a C++17 test case that shows both problems: #define _GLIBCXX_USE_CXX11_ABI 0 #include <string> template<typename T> struct alloc { using value_type = T; alloc() = default; template<typename U> alloc(const alloc<U>&) { } T* allocate(std::size_t n) { if constexpr (std::is_same_v<T, char>) return next.allocate(n + 1) + 1; return next.allocate(n); } void deallocate(T* p, std::size_t n) { if constexpr (std::is_same_v<T, char>) return next.deallocate(p - 1, n + 1); return next.deallocate(p, n); } [[no_unique_address]] std::allocator<T> next; bool operator==(const alloc<T>&) const { return true; } }; template<typename C> using String = std::basic_string<C, std::char_traits<C>, alloc<C>>; int main() { String<long double> sd(2, 0.0L); return sd[1]; } This results in loads of UBsan errors like: /usr/include/c++/13/bits/cow_string.h:3604:24: runtime error: member access within misaligned address 0x0000006f22b1 for type 'struct _Rep', which requires 8 byte alignment 0x0000006f22b1: note: pointer points here 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ ... /usr/include/c++/13/bits/char_traits.h:307:15: runtime error: store to misaligned address 0x0000006f22c9 for type 'char_type', which requires 16 byte alignment 0x0000006f22c9: note: pointer points here 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ ... /usr/include/c++/13/bits/cow_string.h:252:46: runtime error: reference binding to misaligned address 0x0000006f22e9 for type 'char_type', which requires 16 byte alignment 0x0000006f22e9: note: pointer points here 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ ... /usr/include/c++/13/ext/atomicity.h:84:18: runtime error: load of misaligned address 0x0000006f22c1 for type '_Atomic_word', which requires 4 byte alignment 0x0000006f22c1: note: pointer points here 00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ It seems to me that we can just do: struct __attribute__((__aligned__(__alignof__(_CharT)))) _Rep_base { size_type _M_length; size_type _M_capacity; _Atomic_word _M_refcount; }; And then stop allocating raw bytes (with alignment 1) to place the _Rep into, and use this allocator type instead: typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Rep>::other _Rep_alloc; Then of course we need to adjust the size that we (de)allocate, to be in units of sizeof(_Rep) not bytes.