我有一个std::map
:
std::map<uint64_t, unique_ptr<struct stats>> profile_stats;
我的插入和删除功能如下:
插入:
WriteLock(profile_stats_lock);
profile_stats_it it = profile_stats.find(id);
if (it == profile_stats.end()) {
profile_stats[id] = unique_ptr<stats>(new stats());
}
删除:
WriteLock(profile_stats_lock);
profile_stats_it it = profile_stats.find(id);
if (it != profile_stats.end()) {
profile_stats.erase(it);
}
当迭代器在delete函数中被擦除时,插入期间分配的new stats()
的动态内存会被破坏吗?或者我应该做些什么来显式删除唯一指针所指向的动态内存?
当迭代器在delete函数中被擦除时,插入期间分配的
new stats()
的动态内存会被破坏吗?
是。这就是首先使用CCD_ 4的全部意义。当它本身被破坏时,例如当它因任何原因从std::map
中删除时,它将为您释放new
的内存。
附带说明一下,在插入函数中,应该使用std::map::emplace()
(或std::map::insert()
(而不是std::map::operator[]
。operator[]
在映射中搜索匹配的关键字,然后如果找不到关键字则插入新元素。由于您已经从find()
知道找不到id
,因此再次对整个地图执行第二次扫描只是浪费了开销。
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args && ... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
...
WriteLock(profile_stats_lock);
profile_stats_it it = profile_stats.find(id);
if (it == profile_stats.end()) {
profile_stats.emplace(id, make_unique<stats>());
}
或者,如果你不介意浪费一个可能未使用的new
,你可以简单地省略find()
,因为如果密钥已经存在,emplace()
(和insert()
(将不会执行插入:
WriteLock(profile_stats_lock);
profile_stats.emplace(id, make_unique<stats>());
或者,您可以跳过分配stats
,除非实际插入了新的映射元素:
WriteLock(profile_stats_lock);
auto res = profile_stats.emplace(id, nullptr);
if (res.second)
res.first->second = make_unique<stats>();
使用这样的智能指针的全部意义在于它是全自动的。
当迭代器在delete函数中被擦除时,插入期间分配的
new stats()
的动态内存会被破坏吗?
是。当映射本身被破坏时,映射中剩余的任何此类指针也将被正确释放。
还要注意,std::make_unique<stats>()
比std::unique_ptr<stats>(new stats())
更安全,而且只需要对类型进行一次命名。