在以唯一ptr为值的C++映射中,动态内存何时会被销毁

When will the dynamic memory be destroyed in a C++ map with unique ptr as value?

本文关键字:内存 动态 何时会 映射 ptr 唯一 C++      更新时间:2023-10-16

我有一个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())更安全,而且只需要对类型进行一次命名。