Skip to content

Commit 8b0a3b9

Browse files
fix for issue #45 (#46)
fixes #45
1 parent 4c9eae1 commit 8b0a3b9

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

cetlvast/suites/unittest/test_pf17_monotonic_buffer_resource.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,24 @@ TYPED_TEST(TestMonotonicBufferResource, TestAllocationOrder)
103103
void* upstream_memory = subject.allocate(size_bytes);
104104
ASSERT_NE(nullptr, upstream_memory);
105105
}
106+
107+
// +----------------------------------------------------------------------+
108+
109+
/// Verify fix for issue #45
110+
TYPED_TEST(TestMonotonicBufferResource, TestIssue45)
111+
{
112+
constexpr std::size_t size_bytes = 1024;
113+
std::array<cetl::byte, size_bytes> buffer{};
114+
TypeParam subject{buffer.data(), buffer.size(), cetlvast::MRH::null_memory_resource<TypeParam>()};
115+
for(std::size_t i = 0; i < 1024 / (2 * alignof(cetl::byte)); ++i)
116+
{
117+
void* memory0 = subject.allocate(1, alignof(cetl::byte));
118+
ASSERT_NE(nullptr, memory0);
119+
void* memory1 = subject.allocate(1, alignof(cetl::byte));
120+
ASSERT_NE(memory0, memory1);
121+
ASSERT_LT(memory0, memory1);
122+
std::ptrdiff_t range = static_cast<unsigned char*>(memory1) - static_cast<unsigned char*>(memory0);
123+
ASSERT_GE(range, sizeof(cetl::byte));
124+
}
125+
subject.release();
126+
}

include/cetl/pf17/memory_resource.hpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -742,12 +742,23 @@ class basic_monotonic_buffer_resource : public memory_resource
742742
void* result = nullptr;
743743
if (current_buffer_->buffer && current_buffer_->remaining_buffer_size >= size_bytes)
744744
{
745-
void* buffer = current_buffer_->buffer;
746-
std::size_t buffer_size = current_buffer_->remaining_buffer_size;
747-
result = std::align(alignment, size_bytes, buffer, buffer_size);
745+
CETL_DEBUG_ASSERT(current_buffer_->buffer_size >= current_buffer_->remaining_buffer_size,
746+
"remaining_buffer_size exceeded total buffer size? We have corrupt internal logic.");
747+
const std::size_t current_buffer_size =
748+
current_buffer_->buffer_size - current_buffer_->remaining_buffer_size;
749+
void* buffer = &static_cast<unsigned char*>(current_buffer_->buffer)[current_buffer_size];
750+
std::size_t remaining_aligned_size = current_buffer_->remaining_buffer_size;
751+
result = std::align(alignment, size_bytes, buffer, remaining_aligned_size);
748752
if (result)
749753
{
750-
current_buffer_->remaining_buffer_size = buffer_size - size_bytes;
754+
CETL_DEBUG_ASSERT(remaining_aligned_size <= current_buffer_->remaining_buffer_size,
755+
"std::align must never increase the space parameter");
756+
const std::size_t buffer_used =
757+
size_bytes + (current_buffer_->remaining_buffer_size - remaining_aligned_size);
758+
CETL_DEBUG_ASSERT(buffer_used <= current_buffer_->remaining_buffer_size,
759+
"std::align must never return non-null if there isn't enough buffer remaining to "
760+
"align the pointer.");
761+
current_buffer_->remaining_buffer_size -= buffer_used;
751762
}
752763
}
753764
return result;

0 commit comments

Comments
 (0)