* Xi Xue via Gcc-help <gcc-help@xxxxxxxxxxx> [2023-12-24 00:50]: > tw.cpp:53:19: runtime error: member access within address 0x7fe7f52ff800 which does not point to an object of type 'CachedObj' > 0x7fe7f52ff800: note: object has invalid vptr > 00 00 00 00 be be be be be be be be be be be be be be be be be be be be be be be be be be be be > ^~~~~~~~~~~~~~~~~~~~~~~ > invalid vptr > tw.cpp:41:39: runtime error: member access within address 0x7fe7f53ff7c0 which does not point to an object of type 'CachedObj' > 0x7fe7f53ff7c0: note: object has invalid vptr > 00 00 00 00 00 00 00 00 00 00 00 00 a0 f7 3f f5 e7 7f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > ^~~~~~~~~~~~~~~~~~~~~~~ > invalid vptr > I am referring to a derived class. Access to the "next" member of the base class.Is this a runtime error? I think you are missing a constructor call: > template <class T> void *CachedObj<T>::operator new(size_t sz) > { > if (sz != sizeof(T)) > throw std::runtime_error( > "CachedObj:wrong size object in operator new"); > if (!freeStore) { > T *array = alloc_mem.allocate(chunk); > for (size_t i = 0; i != chunk; ++i) > add_to_freelist(&array[i]); Here add_to_freelist is called with a pointer to uninitialized storage (see https://en.cppreference.com/w/cpp/memory/allocator/allocate: "Allocates n * sizeof(T) bytes of uninitialized storage") The function stores the pointer to the uninitalized memory in freeStore. > } > T *p = freeStore; > freeStore = freeStore->CachedObj<T>::next; This treats freeStore as an initialized object and accesses its member (but there doesn't seem to be any constructor call to actually initialize the object). So I think UBSan is correct here. > return p; > } > > template <class T> void CachedObj<T>::operator delete(void *p, size_t) > { > if (p != 0) > add_to_freelist(static_cast<T *>(p)); > } > template <class T> void CachedObj<T>::add_to_freelist(T *p) > { > p->CachedObj<T>::next = freeStore; > freeStore = p; > } Best regards, Thomas