From cf444e53094c10fadebe67488efb5802843657f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=A4=B4=E4=BA=91?= Date: Mon, 1 Dec 2025 09:24:58 +0000 Subject: [PATCH] fix(container_allocator): Fix MSVC compilation by correcting allocator semantics ROOT CAUSE: The allocate() function was incorrectly constructing objects during memory allocation, violating C++ allocator requirements. MSVC's std::_Tree_node has a deleted default constructor, causing compilation failure. CHANGES: - container_allocator::allocate() now only allocates raw memory without constructing objects (removed mem::$new and ipc::construct calls) - container_allocator::deallocate() now only frees memory without destroying objects (removed mem::$delete and ipc::destroy_n calls) WHY THIS FIXES THE ISSUE: C++ allocator semantics require strict separation: * allocate() -> raw memory allocation only * construct() -> object construction with proper arguments * destroy() -> object destruction * deallocate() -> memory deallocation only Standard containers (like std::map) call construct() with proper arguments (key, value) to initialize nodes, not allocate(). Since std::_Tree_node in MSVC has no default constructor (= delete), attempting to construct it without arguments always fails. Fixes MSVC 2017 compilation error: error C2280: 'std::_Tree_node<...>::_Tree_node(void)': attempting to reference a deleted function --- include/libipc/mem/container_allocator.h | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/include/libipc/mem/container_allocator.h b/include/libipc/mem/container_allocator.h index 4087b00..97b8449 100644 --- a/include/libipc/mem/container_allocator.h +++ b/include/libipc/mem/container_allocator.h @@ -63,26 +63,18 @@ public: pointer allocate(size_type count) noexcept { if (count == 0) return nullptr; if (count > this->max_size()) return nullptr; - if (count == 1) { - return mem::$new(); - } else { - void *p = mem::alloc(sizeof(value_type) * count); - if (p == nullptr) return nullptr; - for (std::size_t i = 0; i < count; ++i) { - std::ignore = ipc::construct(static_cast(p) + sizeof(value_type) * i); - } - return static_cast(p); - } + // Allocate raw memory without constructing objects + // Construction should be done by construct() member function + void *p = mem::alloc(sizeof(value_type) * count); + return static_cast(p); } void deallocate(pointer p, size_type count) noexcept { if (count == 0) return; if (count > this->max_size()) return; - if (count == 1) { - mem::$delete(p); - } else { - mem::free(ipc::destroy_n(p, count), sizeof(value_type) * count); - } + // Deallocate raw memory without destroying objects + // Destruction should be done by destroy() member function before deallocate + mem::free(p, sizeof(value_type) * count); } template