Last active
August 7, 2020 17:23
-
-
Save totalgee/a19831f6b4ea5f249606af21ba1a1bf0 to your computer and use it in GitHub Desktop.
remove_if bug (vs find_if)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Run this code here: https://coliru.stacked-crooked.com/a/1a9ad442077cd0f6 | |
#include <vector> | |
#include <algorithm> | |
#include <iostream> | |
#include <memory> | |
int main() | |
{ | |
std::vector<std::unique_ptr<int>> vec; | |
vec.push_back(std::make_unique<int>(3)); | |
vec.push_back(std::make_unique<int>(5)); | |
vec.push_back(std::make_unique<int>(7)); | |
std::cout << "Original vector\n"; | |
for (auto const& elem : vec) { | |
std::cout << " [" << elem.get() << "] " << *elem << std::endl; | |
} | |
constexpr bool brokenCode = false; | |
constexpr int searchValue{5}; | |
auto const rem = [&]{ | |
// If you remove_if(), the unique_ptr will be moved from, thus nullified, | |
// so we'll get undefined behaviour when trying to dereference it later. | |
// Better to find_if()! The vec.erase() still works fine when the iterator | |
// is not at the end of the vector. | |
if (brokenCode) | |
return std::remove_if(vec.begin(), vec.end(), [&](auto const& elem) { return *elem == searchValue; }); | |
else | |
return std::find_if(vec.begin(), vec.end(), [&](auto const& elem) { return *elem == searchValue; }); | |
}(); | |
std::cout << "Found unique_ptr: [" << rem->get() << "] with value: " << **rem << std::endl; | |
vec.erase(rem); | |
std::cout << "\nFinal vector\n"; | |
for (auto const& elem : vec) { | |
std::cout << " [" << elem.get() << "] " << *elem << std::endl; | |
} | |
} | |
// Possible output when brokenCode is false: | |
// ========== | |
// Original vector | |
// [0x2293c20] 3 | |
// [0x2293c60] 5 | |
// [0x2293c40] 7 | |
// Found unique_ptr: [0x2293c60] with value: 5 | |
// | |
// Final vector | |
// [0x2293c20] 3 | |
// [0x2293c40] 7 | |
// Possible output when brokenCode is true: | |
// ========== | |
// Original vector | |
// [0x1349c20] 3 | |
// [0x1349c60] 5 | |
// [0x1349c40] 7 | |
// bash: line 7: 14344 Segmentation fault (core dumped) ./a.out |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment