diff options
author | fanquake <fanquake@gmail.com> | 2023-09-15 09:47:59 +0100 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2023-09-15 10:04:41 +0100 |
commit | 8ef672937e572e16671fdbfdb5a90eaa882e6ee1 (patch) | |
tree | eb4ceaaa118f3b9c0fb1ff57cfc11e07d8c14419 /src/test | |
parent | 459272d639b9547f68000d2b9a5a0d991d477de5 (diff) | |
parent | 3fcd7fc7ff563bdc0e2bba66b4cbe72d898c876e (diff) |
Merge bitcoin/bitcoin#28452: Do not use std::vector = {} to release memory
3fcd7fc7ff563bdc0e2bba66b4cbe72d898c876e Do not use std::vector = {} to release memory (Pieter Wuille)
Pull request description:
It appears that invoking `v = {};` for an `std::vector<...> v` is equivalent to `v.clear()`, which does not release its allocated memory. There are a number of places in the codebase where it appears to be used for that purpose however (mostly written by me). Replace those with `std::vector<...>{}.swap(v);` (using a helper function `ClearShrink` in util/vector.h).
To explain what is going on: `v = {...};` is equivalent in general to `v.operator=({...});`. For many types, the `{}` is converted to the type of `v`, and then assigned to `v` - which for `std::vector` would ordinarily have the effect of clearing its memory (constructing a new empty vector, and then move-assigning it to `v`). However, since `std::vector<T>` has an `operator=(std::initializer_list<T>)` defined, it has precedence (since no implicit conversion is needed), and with an empty list, that is equivalent to `clear()`.
I did consider using `v = std::vector<T>{};` as replacement for `v = {};` instances where memory releasing is desired, but it appears that it does not actually work universally either. `V{}.swap(v);` does.
ACKs for top commit:
ajtowns:
utACK 3fcd7fc7ff563bdc0e2bba66b4cbe72d898c876e
stickies-v:
ACK 3fcd7fc7ff563bdc0e2bba66b4cbe72d898c876e
theStack:
Code-review ACK 3fcd7fc7ff563bdc0e2bba66b4cbe72d898c876e
Tree-SHA512: 6148558126ec3c8cfd6daee167ec1c67b360cf1dff2cbc132bd71768337cf9bc4dda3e5a9cf7da4f7457d2123288eeba77dd78f3a17fa2cfd9c6758262950cc5
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/util_tests.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 26677bfa55..67f71bd266 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1791,4 +1791,29 @@ BOOST_AUTO_TEST_CASE(util_WriteBinaryFile) BOOST_CHECK(valid); BOOST_CHECK_EQUAL(actual_text, expected_text); } + +BOOST_AUTO_TEST_CASE(clearshrink_test) +{ + { + std::vector<uint8_t> v = {1, 2, 3}; + ClearShrink(v); + BOOST_CHECK_EQUAL(v.size(), 0); + BOOST_CHECK_EQUAL(v.capacity(), 0); + } + + { + std::vector<bool> v = {false, true, false, false, true, true}; + ClearShrink(v); + BOOST_CHECK_EQUAL(v.size(), 0); + BOOST_CHECK_EQUAL(v.capacity(), 0); + } + + { + std::deque<int> v = {1, 3, 3, 7}; + ClearShrink(v); + BOOST_CHECK_EQUAL(v.size(), 0); + // std::deque has no capacity() we can observe. + } +} + BOOST_AUTO_TEST_SUITE_END() |