Skip to content

Commit 4fa3489

Browse files
mergify[bot]Chen Lihui
andauthored
fix mismatched issue if using zero_allocate (#1995) (#2026)
* fix mismatched issue if uzing zero_allocated Signed-off-by: Chen Lihui <[email protected]> (cherry picked from commit 9784391) Co-authored-by: Chen Lihui <[email protected]>
1 parent 7f57510 commit 4fa3489

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

rclcpp/include/rclcpp/allocator/allocator_common.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef RCLCPP__ALLOCATOR__ALLOCATOR_COMMON_HPP_
1616
#define RCLCPP__ALLOCATOR__ALLOCATOR_COMMON_HPP_
1717

18+
#include <cstring>
1819
#include <memory>
1920

2021
#include "rcl/allocator.h"
@@ -39,6 +40,22 @@ void * retyped_allocate(size_t size, void * untyped_allocator)
3940
return std::allocator_traits<Alloc>::allocate(*typed_allocator, size);
4041
}
4142

43+
template<typename Alloc>
44+
void * retyped_zero_allocate(size_t number_of_elem, size_t size_of_elem, void * untyped_allocator)
45+
{
46+
auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
47+
if (!typed_allocator) {
48+
throw std::runtime_error("Received incorrect allocator type");
49+
}
50+
size_t size = number_of_elem * size_of_elem;
51+
void * allocated_memory =
52+
std::allocator_traits<Alloc>::allocate(*typed_allocator, size);
53+
if (allocated_memory) {
54+
std::memset(allocated_memory, 0, size);
55+
}
56+
return allocated_memory;
57+
}
58+
4259
template<typename T, typename Alloc>
4360
void retyped_deallocate(void * untyped_pointer, void * untyped_allocator)
4461
{
@@ -73,6 +90,7 @@ rcl_allocator_t get_rcl_allocator(Alloc & allocator)
7390
rcl_allocator_t rcl_allocator = rcl_get_default_allocator();
7491
#ifndef _WIN32
7592
rcl_allocator.allocate = &retyped_allocate<Alloc>;
93+
rcl_allocator.zero_allocate = &retyped_zero_allocate<Alloc>;
7694
rcl_allocator.deallocate = &retyped_deallocate<T, Alloc>;
7795
rcl_allocator.reallocate = &retyped_reallocate<T, Alloc>;
7896
rcl_allocator.state = &allocator;

rclcpp/test/rclcpp/allocator/test_allocator_common.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,53 @@ TEST(TestAllocatorCommon, retyped_allocate) {
5151
EXPECT_NO_THROW(code2());
5252
}
5353

54+
TEST(TestAllocatorCommon, retyped_zero_allocate_basic) {
55+
std::allocator<int> allocator;
56+
void * untyped_allocator = &allocator;
57+
void * allocated_mem =
58+
rclcpp::allocator::retyped_zero_allocate<std::allocator<char>>(20u, 1u, untyped_allocator);
59+
ASSERT_TRUE(nullptr != allocated_mem);
60+
61+
auto code = [&untyped_allocator, allocated_mem]() {
62+
rclcpp::allocator::retyped_deallocate<char, std::allocator<char>>(
63+
allocated_mem, untyped_allocator);
64+
};
65+
EXPECT_NO_THROW(code());
66+
}
67+
68+
TEST(TestAllocatorCommon, retyped_zero_allocate) {
69+
std::allocator<int> allocator;
70+
void * untyped_allocator = &allocator;
71+
void * allocated_mem =
72+
rclcpp::allocator::retyped_zero_allocate<std::allocator<char>>(20u, 1u, untyped_allocator);
73+
// The more natural check here is ASSERT_NE(nullptr, ptr), but clang static
74+
// analysis throws a false-positive memory leak warning. Use ASSERT_TRUE instead.
75+
ASSERT_TRUE(nullptr != allocated_mem);
76+
77+
auto code = [&untyped_allocator, allocated_mem]() {
78+
rclcpp::allocator::retyped_deallocate<int, std::allocator<int>>(
79+
allocated_mem, untyped_allocator);
80+
};
81+
EXPECT_NO_THROW(code());
82+
83+
allocated_mem = allocator.allocate(1);
84+
// The more natural check here is ASSERT_NE(nullptr, ptr), but clang static
85+
// analysis throws a false-positive memory leak warning. Use ASSERT_TRUE instead.
86+
ASSERT_TRUE(nullptr != allocated_mem);
87+
void * reallocated_mem =
88+
rclcpp::allocator::retyped_reallocate<int, std::allocator<int>>(
89+
allocated_mem, 2u, untyped_allocator);
90+
// The more natural check here is ASSERT_NE(nullptr, ptr), but clang static
91+
// analysis throws a false-positive memory leak warning. Use ASSERT_TRUE instead.
92+
ASSERT_TRUE(nullptr != reallocated_mem);
93+
94+
auto code2 = [&untyped_allocator, reallocated_mem]() {
95+
rclcpp::allocator::retyped_deallocate<int, std::allocator<int>>(
96+
reallocated_mem, untyped_allocator);
97+
};
98+
EXPECT_NO_THROW(code2());
99+
}
100+
54101
TEST(TestAllocatorCommon, get_rcl_allocator) {
55102
std::allocator<int> allocator;
56103
auto rcl_allocator = rclcpp::allocator::get_rcl_allocator<int>(allocator);

0 commit comments

Comments
 (0)