I have a std::map<int, std::string>
and my aim is to remove a key-value pair based on a certain condition. For simplicity, let say, it looks like this:
int main(int argc, char const *argv[]) {
std::map<int, std::string> m1;
m1[-2] = "minus two";
m1[-1] = "minus one";
m1[0] = "zero";
m1[3] = "three";
m1[4] = "four";
std::cout << m1.size() << std::endl;
for (auto &&[key, val] : m1) {
std::cout << key << ": " << val << std::endl;
if (key == -2 || key == 3)
m1.erase(key);
}
std::cout << m1.size() << std::endl;
}
Everything looks fine. However, it gives seg fault
upon running:
5
-2: minus two
0:
Segmentation fault (core dumped)
I noticed that this only occurs when I try to erase the very first key-value pair e.g. in the above case: -2: "minus two"
. If I try to erase any other key-value pair (e.g. second key-value pair: -1: "minus one"
) then I don't get seg fault
, e.g.
std::cout << m1.size() << std::endl;
for (auto &&[key, val] : m1) {
std::cout << key << ": " << val << std::endl;
if (key == -1 || key == 3)
m1.erase(key);
}
std::cout << m1.size() << std::endl;
I also noticed that if I erase the first key-value pair outside of the for
loop then I don't get seg fault
e.g.
std::cout << m1.size() << std::endl;
m1.erase(-2);
for (auto &&[key, val] : m1) {
std::cout << key << ": " << val << std::endl;
if (key == -2 || key == 3)
m1.erase(key);
}
std::cout << m1.size() << std::endl;
One more thing that I noticed is that if there are only two key-value pairs then I don't get seg fault
:
m1[-2] = "minus two";
m1[4] = "four";
std::cout << m1.size() << std::endl;
for (auto &&[key, val] : m1) {
std::cout << key << ": " << val << std::endl;
if (key == -2 || key == 3)
m1.erase(key);
}
std::cout << m1.size() << std::endl;
So, is this an expected behavior? If yes then why? Also, in that case, how can I remove/erase the first key-value pair in the for
loop itself? or I have to remove/erase them outside of the for
loop?