STL类指针容器containerclass* 元素clear 注意事项

2024-05-05 16:48

本文主要是介绍STL类指针容器containerclass* 元素clear 注意事项,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在使用 STL 容器时, 涉及到 C++多态(polymorphism)和虚函数时,经常会遇到使用容器存储类指针,当你要删除某个元素或者(erase)或者清空容器(clear)时,直接调用 erase或 clear 函数,指针指向的内存并不会释放,也就是说,对象不会被析构,这时就会导致内存泄漏(memory leak)。
示例代码:

#include <iostream>
#include <list>using std::cout;class Base {
public:virtual ~Base() {}
};class Derived : public Base {};int main(int argc, char* argv[])
{using std::list;list<Base*> ls;ls.push_back(new Base());ls.push_back(new Derived());ls.push_back(new Base());ls.clear();return 0;
}

编译后,使用内存检测工具 valgrind运行内存泄漏检测,得:
这里写图片描述
从图中可以发现程序中有三处内存泄漏,正对应着:

ls.push_back(new Base());
ls.push_back(new Derived());
ls.push_back(new Base());

可见,我们直接调用 clear()后指针对应的内存并没有被释放。而要消除内存泄漏,我们必须添加清理代码,对程序做以下修改:

#include <iostream>
#include <list>using std::cout;class Base {
public:virtual ~Base() {}
};class Derived : public Base {};int main(int argc, char* argv[])
{using std::list;list<Base*> ls;ls.push_back(new Base());ls.push_back(new Derived());ls.push_back(new Base());//添加清理代码for(list<Base*>::iterator it=ls.begin(); it != ls.end(); ++it)delete *it;ls.clear();return 0;
}

再次运行 valgrind, 我们可以发现原来的内存泄漏消失。
这里写图片描述

有关 valgrind 的使用网上有很多,也可以查看本地帮助, 具体命令

valgrind --help

这里只是简单地开启 –leak-check 选项,另外程序在编译时加入“-g”选项,否则看不到发生内存泄漏的代码位置。

这篇关于STL类指针容器containerclass* 元素clear 注意事项的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/962181

相关文章

通过Docker容器部署Python环境的全流程

《通过Docker容器部署Python环境的全流程》在现代化开发流程中,Docker因其轻量化、环境隔离和跨平台一致性的特性,已成为部署Python应用的标准工具,本文将详细演示如何通过Docker容... 目录引言一、docker与python的协同优势二、核心步骤详解三、进阶配置技巧四、生产环境最佳实践

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

Java Stream 并行流简介、使用与注意事项小结

《JavaStream并行流简介、使用与注意事项小结》Java8并行流基于StreamAPI,利用多核CPU提升计算密集型任务效率,但需注意线程安全、顺序不确定及线程池管理,可通过自定义线程池与C... 目录1. 并行流简介​特点:​2. 并行流的简单使用​示例:并行流的基本使用​3. 配合自定义线程池​示

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

Spring Security6.3.x的使用指南与注意事项

《SpringSecurity6.3.x的使用指南与注意事项》SpringSecurity6.3.1基于现代化架构,提供简洁配置、增强默认安全性和OAuth2.1/OIDC支持,采用Lambda... 目录介绍基础配置 (Servlet 应用 - 使用 Lambda DSL)关键配置详解(Lambda DS

把Python列表中的元素移动到开头的三种方法

《把Python列表中的元素移动到开头的三种方法》在Python编程中,我们经常需要对列表(list)进行操作,有时,我们希望将列表中的某个元素移动到最前面,使其成为第一项,本文给大家介绍了把Pyth... 目录一、查找删除插入法1. 找到元素的索引2. 移除元素3. 插入到列表开头二、使用列表切片(Lis

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注