C++ HashMap的一个常见的错误使用

C++新手, 或者即使是用了一段时间也很可能会犯下面的错误
假如果你有一个HashMap, 里面有一个key value pair (key1, value1).
这时你需要插入一个新的key value pair (key2, value2). 这个value2 你想从 value1 copy过来。
这个操作非常基本,非常trival.
你可以想写如下语句

myMap[key2] = myMap.at(key1);

这个语句在绝大多数情况下都是对的。绝大多数测试也能通过。
直到有一天你发现了报一个错, 这个错误叫做 heap-use-after-free.
为什么这么简单的语句会出错?
原因是我们并不知道这句话是左边先执行还是右边先执行?C++并没有对哪边先执行有规定。如果左边先执行,那没有问题。
但是如果右边先执行了,我们取了key1的reference。
这时我们执行左边的语句,由于我们是新插入一个key2, 这时有可能我们的hashMap直接做了一个re hash操作。
如果做了rehash操作,整个map被移动了。
那此时右边的reference不再是valid的了, 可能被换地方了,但我们reference还是指向的以前的reference, 所以这时就出现了heap-use-after-free.
这种错误如果不是在asan mode (address sanitizer mode) 可能根本就不出报错,就一直在那里默默的等待着某一天出错。
正确的写法是先强行copy, 然后再插入。

auto value = myMap.at(key1);
myMap[key2] = std::move(value);

这里用了std::move语法让它不再多copy一次。

你可能感兴趣的:(C++ HashMap的一个常见的错误使用)