Skip to content

Commit c6d883a

Browse files
committed
Fix memory leak
1 parent 370adff commit c6d883a

3 files changed

Lines changed: 39 additions & 5 deletions

File tree

internal/HashMap32.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,17 @@ class HashMap32 : HashFunc, KeyEqual, Allocator {
5454
HashMap32(const HashMap32 &rhs) = delete;
5555
HashMap32 &operator=(const HashMap32 &rhs) = delete;
5656

57-
HashMap32(HashMap32 &&rhs) noexcept { (*this) = std::move(rhs); }
57+
HashMap32(HashMap32 &&rhs) noexcept : ctrl_(nullptr), nodes_(nullptr), capacity_(0), size_(0) {
58+
(*this) = std::move(rhs);
59+
}
5860
HashMap32 &operator=(HashMap32 &&rhs) noexcept {
5961
if (this == &rhs) {
6062
return (*this);
6163
}
64+
if (ctrl_) {
65+
clear();
66+
this->deallocate(ctrl_, mem_size(capacity_));
67+
}
6268
if constexpr (std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
6369
Allocator::operator=(static_cast<Allocator &&>(rhs));
6470
}
@@ -79,6 +85,8 @@ class HashMap32 : HashFunc, KeyEqual, Allocator {
7985
uint32_t size() const { return size_; }
8086
uint32_t capacity() const { return capacity_; }
8187

88+
bool empty() const { return size_ == 0; }
89+
8290
void clear() {
8391
for (uint32_t i = 0; i < capacity_ && size_; i++) {
8492
if (ctrl_[i] & OccupiedBit) {
@@ -185,7 +193,7 @@ class HashMap32 : HashFunc, KeyEqual, Allocator {
185193
}
186194

187195
template <typename K2> V *Find(const uint32_t hash, const K2 &key) {
188-
return const_cast<V *>(const_cast<const HashMap32 *>(this)->Find(hash, key));
196+
return const_cast<V *>(std::as_const(*this).Find(hash, key));
189197
}
190198

191199
Node *GetOrNull(const uint32_t index) {
@@ -330,6 +338,15 @@ class HashMap32 : HashFunc, KeyEqual, Allocator {
330338
return iter_at(next);
331339
}
332340

341+
uint32_t FindOccupiedInRange(const uint32_t start, const uint32_t end) {
342+
for (uint32_t i = start; i < end; ++i) {
343+
if (ctrl_[i] & OccupiedBit) {
344+
return i;
345+
}
346+
}
347+
return end;
348+
}
349+
333350
private:
334351
void CheckRealloc() {
335352
if ((size_ + 1) > uint32_t(0.8f * capacity_)) {

internal/HashSet32.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,26 @@ template <typename K> class Hash {
5656
template <> class Hash<char *> {
5757
public:
5858
uint32_t operator()(const char *s) const { return _str_hash(s); }
59+
uint32_t operator()(const std::string_view &s) const { return _str_hash_len(s.data(), s.size()); }
5960
};
6061

6162
template <> class Hash<const char *> {
6263
public:
6364
uint32_t operator()(const char *s) const { return _str_hash(s); }
65+
uint32_t operator()(const std::string_view &s) const { return _str_hash_len(s.data(), s.size()); }
66+
};
67+
68+
template <> class Hash<std::string_view> {
69+
public:
70+
uint32_t operator()(const std::string &s) const { return _str_hash_len(s.c_str(), s.length()); }
71+
uint32_t operator()(const std::string_view &s) const { return _str_hash_len(s.data(), s.size()); }
72+
uint32_t operator()(const char *s) const { return _str_hash(s); }
6473
};
6574

6675
template <> class Hash<std::string> {
6776
public:
6877
uint32_t operator()(const std::string &s) const { return _str_hash_len(s.c_str(), s.length()); }
78+
uint32_t operator()(const std::string_view &s) const { return _str_hash_len(s.data(), s.size()); }
6979
uint32_t operator()(const char *s) const { return _str_hash(s); }
7080
};
7181

@@ -77,11 +87,13 @@ template <typename K> class Equal : std::equal_to<K> {
7787
template <> class Equal<char *> {
7888
public:
7989
bool operator()(const char *k1, const char *k2) const { return strcmp(k1, k2) == 0; }
90+
bool operator()(const char *k1, std::string_view k2) const { return k2 == k1; }
8091
};
8192

8293
template <> class Equal<const char *> {
8394
public:
8495
bool operator()(const char *k1, const char *k2) const { return strcmp(k1, k2) == 0; }
96+
bool operator()(const char *k1, std::string_view k2) const { return k2 == k1; }
8597
};
8698

8799
template <> class Equal<std::string> {
@@ -138,11 +150,17 @@ class HashSet32 : HashFunc, KeyEqual, Allocator {
138150
HashSet32(const HashSet32 &rhs) = delete;
139151
HashSet32 &operator=(const HashSet32 &rhs) = delete;
140152

141-
HashSet32(HashSet32 &&rhs) noexcept { (*this) = std::move(rhs); }
153+
HashSet32(HashSet32 &&rhs) noexcept : ctrl_(nullptr), nodes_(nullptr), capacity_(0), size_(0) {
154+
(*this) = std::move(rhs);
155+
}
142156
HashSet32 &operator=(HashSet32 &&rhs) noexcept {
143157
if (this == &rhs) {
144158
return (*this);
145159
}
160+
if (ctrl_) {
161+
clear();
162+
this->deallocate(ctrl_, mem_size(capacity_));
163+
}
146164
if constexpr (std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
147165
Allocator::operator=(static_cast<Allocator &&>(rhs));
148166
}
@@ -252,7 +270,7 @@ class HashSet32 : HashFunc, KeyEqual, Allocator {
252270
}
253271

254272
template <typename K2> K *Find(const uint32_t hash, const K2 &key) {
255-
return const_cast<K *>(const_cast<const HashSet32 *>(this)->Find(hash, key));
273+
return const_cast<K *>(std::as_const(*this).Find(hash, key));
256274
}
257275

258276
Node *GetOrNull(const uint32_t index) {

internal/SmallVector.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ template <typename T, typename Allocator = aligned_allocator<T, alignof(T)>> cla
219219
}
220220

221221
T *new_begin = this->allocate(req_capacity);
222-
T *new_end = new_begin + size_;
223222

224223
for (uint32_t i = 0; i < size_; ++i) {
225224
new (new_begin + i) T(std::move(begin_[i]));

0 commit comments

Comments
 (0)