深入解析C++ 中std::map內存管理
1?、基本清空std::map
使用 clear() 可以刪除 map 中的所有元素,銷毀每個元素:
#include <iostream>
#include <map>
int main() {
std::map<int, std::string> myMap;
myMap[1] = "one";
myMap[2] = "two";
std::cout << "Before clear, size: " << myMap.size() << std::endl;
// 清空 map
myMap.clear();
std::cout << "After clear, size: " << myMap.size() << std::endl;
return 0;
}輸出:
Before clear, size: 2
After clear, size: 0
注意:clear() 只是刪除節(jié)點,不一定釋放底層內存池分配的所有內存(STL 可能保留內存用于以后復用)。
2?、使用 swap 徹底釋放內存
為了讓 STL 容器釋放所有內存,可以和一個空 map 交換:
std::map<int, std::string>().swap(myMap);
等價于:
std::map<int, std::string> emptyMap; myMap.swap(emptyMap); // 將 myMap 與空 map 交換
- 優(yōu)點:保證底層內存釋放
- 適合大 map 釋放內存,避免內存泄漏
3?、map 中存儲指針類型的對象
如果 map 中是指針類型,需要先釋放指針指向的內存,否則會泄漏:
#include <map>
#include <string>
#include <iostream>
int main() {
std::map<int, std::string*> myMap;
myMap[1] = new std::string("one");
myMap[2] = new std::string("two");
// 手動釋放指針
for (auto& pair : myMap) {
delete pair.second;
}
myMap.clear(); // 刪除節(jié)點
// 或者徹底釋放內存
std::map<int, std::string*>().swap(myMap);
std::cout << "Map cleared and memory released" << std::endl;
}4?、總結
| 操作 | 內存釋放效果 | 適用場景 |
|---|---|---|
myMap.clear() | 刪除元素,可能不釋放底層節(jié)點內存 | 小型 map 或可重復使用的 map |
std::map<…>().swap(myMap) | 刪除元素,釋放底層內存 | 大型 map,徹底釋放內存 |
對指針類型元素手動 delete | 釋放指針對象占用內存 | map 存儲動態(tài)分配對象 |
5、擴展應用示例-模板化函數free_map_memory內存釋放
下面是一個 模板化函數 free_map_memory,能自動處理 指針和非指針類型 map 的完全釋放,被封裝成可復用工具函數,可以直接應用到開發(fā)項目中,大家可根據自己的需求進行更改。
示例1,常規(guī)版本
#include <map>
#include <type_traits>
#include <memory> // std::addressof
#include <utility> // std::swap
#include <iostream>
template <typename MapType>
void free_map_memory(MapType& m) {
using ValueType = typename MapType::mapped_type;
// 如果 ValueType 是指針類型,先 delete 指針
if constexpr (std::is_pointer_v<ValueType>) {
for (auto& kv : m) {
delete kv.second;
}
}
// 清空 map 元素
m.clear();
// 徹底釋放底層內存
MapType().swap(m);
}
// ------------------- 示例 -------------------
struct MyData {
int x;
MyData(int v) : x(v) {}
};
int main() {
std::map<int, int> normalMap;
normalMap[1] = 100;
normalMap[2] = 200;
std::map<int, MyData*> pointerMap;
pointerMap[1] = new MyData(10);
pointerMap[2] = new MyData(20);
std::cout << "Before free, normalMap size: " << normalMap.size() << std::endl;
std::cout << "Before free, pointerMap size: " << pointerMap.size() << std::endl;
free_map_memory(normalMap);
free_map_memory(pointerMap);
std::cout << "After free, normalMap size: " << normalMap.size() << std::endl;
std::cout << "After free, pointerMap size: " << pointerMap.size() << std::endl;
return 0;
}功能特點
- 自動識別值類型是否為指針:使用
std::is_pointer_v。 - 安全釋放指針類型對象:自動
delete。 - 徹底釋放 map 內存:使用
swap與臨時空 map 交換。 - 通用:支持任何
std::map<Key, Value>類型,包括自定義結構體指針。
示例2,智能指針版本
加強版本能自動識別并處理以下幾類 map:
- 值類型為普通對象
- 值類型為原始指針
- 值類型為
std::unique_ptr或std::shared_ptr
模板函數會自動釋放內容并徹底回收 map 內存。
#include <map>
#include <memory>
#include <type_traits>
#include <utility>
#include <iostream>
template <typename MapType>
void free_map_memory(MapType& m) {
using ValueType = typename MapType::mapped_type;
// 原始指針類型
if constexpr (std::is_pointer_v<ValueType>) {
for (auto& kv : m) {
delete kv.second;
}
}
// unique_ptr 或 shared_ptr 類型
else if constexpr (std::is_same_v<ValueType, std::unique_ptr<typename ValueType::element_type>> ||
std::is_same_v<ValueType, std::shared_ptr<typename ValueType::element_type>>) {
// 智能指針自動釋放,無需手動 delete
}
// 普通對象類型,無需特殊處理
// 清空 map 元素
m.clear();
// 徹底釋放底層內存
MapType().swap(m);
}
// ------------------- 示例 -------------------
struct MyData {
int x;
MyData(int v) : x(v) {}
};
int main() {
// 普通對象 map
std::map<int, int> normalMap{{1,100},{2,200}};
// 原始指針 map
std::map<int, MyData*> pointerMap;
pointerMap[1] = new MyData(10);
pointerMap[2] = new MyData(20);
// unique_ptr map
std::map<int, std::unique_ptr<MyData>> uniquePtrMap;
uniquePtrMap[1] = std::make_unique<MyData>(30);
uniquePtrMap[2] = std::make_unique<MyData>(40);
// shared_ptr map
std::map<int, std::shared_ptr<MyData>> sharedPtrMap;
sharedPtrMap[1] = std::make_shared<MyData>(50);
sharedPtrMap[2] = std::make_shared<MyData>(60);
free_map_memory(normalMap);
free_map_memory(pointerMap);
free_map_memory(uniquePtrMap);
free_map_memory(sharedPtrMap);
std::cout << "All maps freed successfully." << std::endl;
return 0;
}功能特點
- 自動區(qū)分普通對象 / 原始指針 / 智能指針
- 原始指針自動
delete - 智能指針無需手動釋放
- 徹底回收 map 內存,避免底層內存占用
到此這篇關于C++ 中std::map內存管理詳解的文章就介紹到這了,更多相關C++ td::map內存管理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++實現(xiàn)選擇排序(selectionSort)
這篇文章主要為大家詳細介紹了C++實現(xiàn)選擇排序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-04-04
在Visual Studio中配置C++最新版netCDF庫的方法
本文介紹在Windows電腦的Visual Studio軟件中,配置C++ 語言最新版netCDF庫的方法,文中通過圖文結合的形式介紹的非常詳細,具有一定的參考價值,需要的朋友可以參考下2024-03-03
VisualStudio?制作Dynamic?Link?Library動態(tài)鏈接庫文件的詳細過程
這篇文章主要介紹了VisualStudio?制作Dynamic?Link?Library動態(tài)鏈接庫文件的詳細過程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08

