From d2ddce0a37cd5d41e3f5df29f0d10e0b2eb8facf Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 9 Nov 2021 14:52:16 +0100 Subject: [PATCH] :bug: avoid using an invalidated iterator --- include/nlohmann/ordered_map.hpp | 11 ++++++++--- single_include/nlohmann/json.hpp | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/nlohmann/ordered_map.hpp b/include/nlohmann/ordered_map.hpp index 1c161efdd..fb242633c 100644 --- a/include/nlohmann/ordered_map.hpp +++ b/include/nlohmann/ordered_map.hpp @@ -112,11 +112,14 @@ template , iterator erase(iterator first, iterator last) { - auto elements_affected = std::distance(first, last); + const auto offset = std::distance(Container::begin(), first); + const auto elements_affected = std::distance(first, last); // This is the start situation. We need to delete elements_affected // elements (3 in this example: e, f, g), and need to return an // iterator past the last deleted element (h in this example). + // Note that offset is the distance from the start of the vector + // to first. We will need this later. // [ a, b, c, d, e, f, g, h, i, j ] // ^ ^ @@ -149,8 +152,10 @@ template , // ^ ^ // first last - // first is now pointing past the last deleted element - return first; + // first is now pointing past the last deleted element, but we cannot + // use this iterator got invalidated by the resize call. Instead, we + // can return begin() + offset. + return Container::begin() + offset; } size_type count(const Key& key) const diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 3743fb8e0..dffa48d19 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -17499,11 +17499,14 @@ template , iterator erase(iterator first, iterator last) { - auto elements_affected = std::distance(first, last); + const auto offset = std::distance(Container::begin(), first); + const auto elements_affected = std::distance(first, last); // This is the start situation. We need to delete elements_affected // elements (3 in this example: e, f, g), and need to return an // iterator past the last deleted element (h in this example). + // Note that offset is the distance from the start of the vector + // to first. We will need this later. // [ a, b, c, d, e, f, g, h, i, j ] // ^ ^ @@ -17536,8 +17539,10 @@ template , // ^ ^ // first last - // first is now pointing past the last deleted element - return first; + // first is now pointing past the last deleted element, but we cannot + // use this iterator got invalidated by the resize call. Instead, we + // can return begin() + offset. + return Container::begin() + offset; } size_type count(const Key& key) const