Skip to content

Commit 67b6d99

Browse files
sipafanquake
authored andcommitted
Do not use std::vector = {} to release memory
Github-Pull: #28452 Rebased-From: 3fcd7fc
1 parent defdc15 commit 67b6d99

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

src/headerssync.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <pow.h>
88
#include <timedata.h>
99
#include <util/check.h>
10+
#include <util/vector.h>
1011

1112
// The two constants below are computed using the simulation script on
1213
// https://gist.github.com/sipa/016ae445c132cdf65a2791534dfb7ae1
@@ -51,9 +52,9 @@ HeadersSyncState::HeadersSyncState(NodeId id, const Consensus::Params& consensus
5152
void HeadersSyncState::Finalize()
5253
{
5354
Assume(m_download_state != State::FINAL);
54-
m_header_commitments = {};
55+
ClearShrink(m_header_commitments);
5556
m_last_header_received.SetNull();
56-
m_redownloaded_headers = {};
57+
ClearShrink(m_redownloaded_headers);
5758
m_redownload_buffer_last_hash.SetNull();
5859
m_redownload_buffer_first_prev_hash.SetNull();
5960
m_process_all_remaining_headers = false;

src/test/util_tests.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,4 +2782,29 @@ BOOST_AUTO_TEST_CASE(util_WriteBinaryFile)
27822782
BOOST_CHECK(valid);
27832783
BOOST_CHECK_EQUAL(actual_text, expected_text);
27842784
}
2785+
2786+
BOOST_AUTO_TEST_CASE(clearshrink_test)
2787+
{
2788+
{
2789+
std::vector<uint8_t> v = {1, 2, 3};
2790+
ClearShrink(v);
2791+
BOOST_CHECK_EQUAL(v.size(), 0);
2792+
BOOST_CHECK_EQUAL(v.capacity(), 0);
2793+
}
2794+
2795+
{
2796+
std::vector<bool> v = {false, true, false, false, true, true};
2797+
ClearShrink(v);
2798+
BOOST_CHECK_EQUAL(v.size(), 0);
2799+
BOOST_CHECK_EQUAL(v.capacity(), 0);
2800+
}
2801+
2802+
{
2803+
std::deque<int> v = {1, 3, 3, 7};
2804+
ClearShrink(v);
2805+
BOOST_CHECK_EQUAL(v.size(), 0);
2806+
// std::deque has no capacity() we can observe.
2807+
}
2808+
}
2809+
27852810
BOOST_AUTO_TEST_SUITE_END()

src/util/vector.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,22 @@ inline V Cat(V v1, const V& v2)
4949
return v1;
5050
}
5151

52+
/** Clear a vector (or std::deque) and release its allocated memory. */
53+
template<typename V>
54+
inline void ClearShrink(V& v) noexcept
55+
{
56+
// There are various ways to clear a vector and release its memory:
57+
//
58+
// 1. V{}.swap(v)
59+
// 2. v = V{}
60+
// 3. v = {}; v.shrink_to_fit();
61+
// 4. v.clear(); v.shrink_to_fit();
62+
//
63+
// (2) does not appear to release memory in glibc debug mode, even if v.shrink_to_fit()
64+
// follows. (3) and (4) rely on std::vector::shrink_to_fit, which is only a non-binding
65+
// request. Therefore, we use method (1).
66+
67+
V{}.swap(v);
68+
}
69+
5270
#endif // BITCOIN_UTIL_VECTOR_H

0 commit comments

Comments
 (0)