C++ map clear内存泄漏问题

这篇具有很好参考价值的文章主要介绍了C++ map clear内存泄漏问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

map值存的是指针

map自带的clear()函数会清空map里存储的所有内容,但如果map值存储的是指针,则里面的值不会被清空,会造成内存泄漏,所以值为指针的map必须用迭代器清空。

使用erase迭代删除
迭代器删除值为指针的map,一定要注意迭代器使用正确,一旦迭代器失效程序就会崩溃。

std::map<int, HHH*> test_map;
HHH* h1 = new HHH;
HHH* h2 = new HHH;
test_map[0] = h1;
test_map[1] = h2;


// 删除
std::map<int, HHH*>::iterator iter;
for (iter = test_map.begin(); iter != test_map.end();)
{
    delete iter->second;
    iter->second = nullptr;
    // 删除迭代器元素先加加再删,否则迭代器失效程序崩溃!!!(必须iter++不可以++iter)
    test_map.erase(iter++);
}

map值存储的不是指针

std::map<int,int> test_map;
test_map[0] = 0;
test_map[1] = 0;

// 删除
test_map.clear(); //值为指针不要这样删除

调用clear()函数之前先把值里的指针的值通过迭代器delete

	std::map<int, HHH*> test_map;
    HHH* h1 = new HHH;
    HHH* h2 = new HHH;
    test_map[0] = h1;
    test_map[1] = h2;

    // 删除
    std::map<int, HHH*>::iterator iter;
    for (iter = test_map.begin(); iter != test_map.end();)
    {
        delete iter->second;
        iter->second = nullptr;
        // 删除迭代器元素先加加再删,否则迭代器失效程序崩溃!!!(必须iter++不可以++iter)
        iter++;
    }
    test_map.clear();

map中存储的是智能指针

若是采用了智能指针,则无需单独delete,智能指针,会自动释放内存

std::map<int, std::shared_ptr<int>> m_map;
m_map[0] = std::make_shared<int>();
delete m_map[0]; //错误

清空map释放内存

若需要多次使用同一个map,其中每次使用后都clear清空,多次之后,可能出现内存泄露,这是因为map的空间便没有释放,所以得使用swap清空。

如果内存错误提示如下

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000000010ca227 in tcmalloc::SLL_Next(void*) ()
(gdb) bt
#0  0x00000000010ca227 in tcmalloc::SLL_Next(void*) ()
#1  0x00000000010ca2b8 in tcmalloc::SLL_TryPop(void**, void**) ()
#2  0x00000000010ca715 in tcmalloc::ThreadCache::FreeList::TryPop(void**) ()
#3  0x00000000011ebe6c in tc_newarray ()

STL容器调用clear()方法,通常只是使得容器内部的对象通通析构,但容器本身的内存无法得到释放。即篮子里面东西拿走了,篮子占的空间还在,这样是为了方便下次存放新的对象时,不需要再次申请空间。即clear()后,容器的size为0,但capacity不变。通过swap()空容器,来彻底释放容器占用的capacity。

#include<map>
#include<vector>
#include<string>
#include <iostream>
#include <time.h>
using namespace std;
 
class useTest
{
public:
    useTest() {};
    map<string,string> testMap;
    vector<string> testVertor;
    string id;
};
 
void clearData(map<int, useTest>& needClearMap)
{
    clock_t  startt = clock();
 
    //分别通过去注释测试下面四种情况
 
    //使用clear
    //needClearMap.clear();
 
    //使用swap
    map<int, useTest> uu;
    needClearMap.swap(uu);
 
    //使用erase
    //needClearMap.erase(needClearMap.begin(), needClearMap.end());
 
    //使用for erase
    //for (auto iter = needClearMap.begin(); iter != needClearMap.end(); iter = needClearMap.erase(iter)) {}
    double sec = double(clock() - startt) / CLOCKS_PER_SEC;
    std::cout << "In Clear Cost Time:" << sec << endl;
}
 
void test()
{
    map<int, useTest> needClearMap;
    for (size_t i = 0; i <= 10000; ++i)
    {
        useTest uT;
        for (size_t ii = 0; ii <= 1000; ++ii)
        {
            uT.testMap[to_string(ii)] = "我是测试,我是测试,我就是测试string";
            uT.testVertor.push_back("我也是测试,我也是测试,我就是测试string");
        }
        uT.id = to_string(i);
        //cout << i << endl;
        needClearMap[i] = uT;
    }
    clock_t  startt = clock();
    clearData(needClearMap);
    double sec = double(clock() - startt) / CLOCKS_PER_SEC;
    std::cout << "clearData Cost Time:" << sec << endl;
}
 
int main()
{
    for (size_t i = 0; i < 10; ++i)
    {
        test();
    }
    getchar();
}

就单单实现某个map清空来说,swap效率最高,几乎是0耗时。但是当退出整个函数,释放swap转移到的临时对象要耗一定的时间。erase效率稍微比clear高。通过for循环erase好似效率又高点。

对于map、set、unordered_map等容器,调用clear()、swap()都无法使得内存真正释放。虽然很多地方谈到,这一现象(内存被保留下来)是正常的,并不需要担心。但是当大量使用堆内存存放不同的数据结构,会造成严重的内存碎片从而导致内存泄漏问题。

#include <iostream>
#include <map>
#include <malloc.h>
using namespace std;
void func()
{
        map<int,string> mp;
        int i = 5000000;
        while(i--)
            mp.insert(make_pair(i,string("hell000o")));
        map<int,string>().swap(mp); //swap
}
int main()
{
        func();
        cout <<"done."<<endl;
        malloc_trim(0);
        while(1);
}
 

只需添加一行,malloc_trim(0); 这一行代码会将空闲的堆内存归还给操作系统,供其他进程使用。文章来源地址https://www.toymoban.com/news/detail-700745.html

到了这里,关于C++ map clear内存泄漏问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用Map.clear()、List.clear()方法,清空时注意!

    对 Map、List 对象进行清空操作时,常常会使用 clear() 方法。 例如,清空 Map 换做 List 也是同样的用法 本文想要说的是,需要注意,如果使用clear()方法, Map被清空的同时,原本对Map的引用会一起被清空!!! 代码举例: 这段代码也很简单,两层循环。 最里层向 listTemp 中添加

    2024年01月20日
    浏览(47)
  • 使用asan检测内存泄漏、堆栈溢出等问题

    操作过程参考:链接 缘起:程序在移动端崩溃,mac端复现不了,于是在写个崩溃位置函数的调用demo,使用ASAN工具进行排查。 验证过程 1、代码 main.cpp 使用附加ASAN工具的方式进行编译: 执行: 没有问题,以上是验证过程,如有问题执行时ASAN会提示有问题的相关位置。 介绍

    2024年02月11日
    浏览(63)
  • [JAVA]websocket引起的内存泄漏问题排查

    项目运行一天后出现了 java.lang.OutOfMemoryError: GC overhead limit exceeded 的错误,造成系统宕机。这说明给JVM分配的内存已经耗尽,不足以支撑垃圾回收进行内存回收工作,意味着程序占用的内存随着时间大小提升,最终耗尽。 2.1 宏观分析 从字面意思来看,GC(garbage collection)所需

    2024年02月13日
    浏览(52)
  • ()自定义DialogFragment以及解决其内存泄漏问题

    日常开发中,dialog是常见的功能,我们时常需要弹出来一些弹框提示用户 今天就定义了一个方便的dialog基类BaseSimpleDialogFragment, 支持快速地显示一个dialog 主要功能有: initAnimation:设置入场和出场动画 getGravity:设置dialog显示位置(屏幕上,中,下) getCanceledOnTouchOutside:点

    2024年02月15日
    浏览(39)
  • 【Go】常见的四个内存泄漏问题

    1、这里更多的是由于channel+for+select导致的,错误的写法导致了发送者或接收者没有发现channel已经关闭,任务已经结束了,却仍然在尝试输入输出https://geektutu.com/post/hpg-exit-goroutine.html 不要把map用作全局

    2024年02月13日
    浏览(44)
  • 【Android】一个contentResolver引起的内存泄漏问题分析

    长时间的压力测试后,系统发生了重启,报错log如下 JNI ERROR (app bug): global reference table overflow (max=51200) global reference table overflow的log 08-08 04:11:53.052912   973  3243 F zygote64: indirect_reference_table.cc:256] JNI ERROR (app bug): global reference table overflow (max=51200) 08-08 04:11:53.053014   973  3243 F z

    2024年02月08日
    浏览(37)
  • 使用Visual Leak Detector排查内存泄漏问题

    目录 1、VLD工具概述 2、下载、安装VLD 2.1、下载VLD 2.2、安装VLD 3、VLD安装目录及文件说明

    2024年02月07日
    浏览(45)
  • 前端面试宝典~Symbol、相同的Set、Getter、控制动画、js中哪些操作会造成内存泄漏?等......

    html页面的骨架,相当于人的骨头,只有骨头是不是看着有点瘆人,只有HTML也是如此。 css,相当于把骨架修饰起来,相当于人的皮肉。 js(javascripts),动起来,相当于人的血液,大脑等一切能使人动起来的器官或者其他的。 在刷题之前先介绍一下牛客。Leetcode有的刷题牛客都有,

    2024年01月20日
    浏览(47)
  • 【C++】深入探讨内存管理:malloc/free与new/delete的区别以及如何避免内存泄漏

    在软件开发中,正确处理内存管理是至关重要的一环。在C++编程中,我们经常会用到动态内存管理的工具,比如 malloc/free 和 new/delete 。本文将深入探讨 malloc/free 与 new/delete 之间的区别,以及如何有效地避免内存泄漏问题。 都是用于从堆上申请空间,并需要手动释放。 mallo

    2024年02月22日
    浏览(54)
  • 记录--解决前端内存泄漏:问题概览与实用解决方案

    内存泄漏是前端开发中的一个常见问题,可能导致项目变得缓慢、不稳定甚至崩溃。在本文中,我们将深入探讨在JavaScript、Vue和React项目中可能导致内存泄漏的情况,并提供详细的代码示例,以帮助开发人员更好地理解和解决这些问题。 1. 未正确清理事件处理器 JavaScript中的

    2024年02月11日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包