Skip to content

Commit 5e266f5

Browse files
committed
fix(container_allocator): Fix MSVC error 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: 1. container_allocator::allocate() - Now only allocates raw memory without constructing objects (removed mem::$new and ipc::construct calls) 2. 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 * construct() -> object construction * destroy() -> object destruction * deallocate() -> memory deallocation - std::map and other containers call construct() with proper arguments (key, value) to initialize nodes, not allocate() - std::_Tree_node in MSVC has no default constructor (= delete), so attempting to construct it without arguments always fails - The previous code tried to default-construct objects in allocate(), which is both semantically wrong and impossible for _Tree_node PREVIOUS FIX (uninitialized.h): The earlier fix to uninitialized.h was insufficient - even with correct T() vs T{} handling, you cannot default-construct a type with deleted default constructor. Fixes MSVC 2017 compilation error: error C2280: attempting to reference a deleted function
1 parent d65eafe commit 5e266f5

File tree

1 file changed

+7
-15
lines changed

1 file changed

+7
-15
lines changed

include/libipc/mem/container_allocator.h

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,26 +63,18 @@ class container_allocator {
6363
pointer allocate(size_type count) noexcept {
6464
if (count == 0) return nullptr;
6565
if (count > this->max_size()) return nullptr;
66-
if (count == 1) {
67-
return mem::$new<value_type>();
68-
} else {
69-
void *p = mem::alloc(sizeof(value_type) * count);
70-
if (p == nullptr) return nullptr;
71-
for (std::size_t i = 0; i < count; ++i) {
72-
std::ignore = ipc::construct<value_type>(static_cast<byte *>(p) + sizeof(value_type) * i);
73-
}
74-
return static_cast<pointer>(p);
75-
}
66+
// Allocate raw memory without constructing objects
67+
// Construction should be done by construct() member function
68+
void *p = mem::alloc(sizeof(value_type) * count);
69+
return static_cast<pointer>(p);
7670
}
7771

7872
void deallocate(pointer p, size_type count) noexcept {
7973
if (count == 0) return;
8074
if (count > this->max_size()) return;
81-
if (count == 1) {
82-
mem::$delete(p);
83-
} else {
84-
mem::free(ipc::destroy_n(p, count), sizeof(value_type) * count);
85-
}
75+
// Deallocate raw memory without destroying objects
76+
// Destruction should be done by destroy() member function before deallocate
77+
mem::free(p, sizeof(value_type) * count);
8678
}
8779

8880
template <typename... P>

0 commit comments

Comments
 (0)