当前位置: 首页 > news >正文

C++常见内存泄漏案例分析以及解决方案

C++ 常见内存泄漏案例分析以及解决方案

1. 分配与释放不匹配

在动态内存管理中,使用new操作符分配的内存必须通过delete操作符显式释放。若未遵循这一规则,将导致内存泄漏。例如:

int *p = new int;
p = new int; // 错误:未释放先前分配的内存
delete p; // 仅释放最后一次分配的内存

对于使用new[]分配的数组,必须使用delete[]进行释放,否则同样会导致内存泄漏:

int* ptr = new int[2];
// 使用ptr...
delete[] ptr; // 正确:使用delete[]释放数组

类似地,使用malloc分配的内存必须通过free释放,否则也会造成内存泄漏:

int *p = (int*)malloc(sizeof(int));
p = (int*)malloc(sizeof(int)); // 错误:未释放先前分配的内存
free(p); // 正确:释放内存

此外,库函数如strdup()返回的内存需要显式释放,否则也会造成内存泄漏:

char* dup_str = strdup("example");
free(dup_str); // 释放内存,避免内存泄漏

2. 嵌套指针的不完全释放

在处理嵌套指针时,必须确保释放每个层级的内存。仅释放外层内存而不释放内层指针会导致内存泄漏:

int **b = new int*[M];
for(int i = 0; i < M; i++) {b[i] = new int[N];
}
// 释放内存
for(int i = 0; i < M; i++) {delete[] b[i];
}
delete[] b;

3. 基类析构函数非虚

在多态情况下,基类的析构函数必须是虚函数,以确保通过基类指针删除派生类对象时,能够正确调用派生类的析构函数,避免内存泄漏:

class A {
public:virtual ~A() {} // 正确:虚析构函数
};class B : public A {
public:~B() {}
};

4. 使用free不触发析构

使用malloc分配的类对象不会触发析构函数,导致内存泄漏:

MyClass* obj = (MyClass*)malloc(sizeof(MyClass));
new(obj) MyClass(44);
free(obj); // 错误:不会调用析构函数

正确的做法是使用new和delete:

MyClass* obj = new MyClass(44);
delete obj; // 正确:调用析构函数

5. 更新未释放内存的指针

在更新指针指向的内存时,必须先释放旧内存,否则会造成内存泄漏:

class Student {
private:char* mName;
public:// 构造函数和析构函数...void setName(const char* name) {if (this->mName != nullptr) {delete[] this->mName;}// 分配新内存...}
};

6. 无法删除引用指向的内存地址

返回动态分配内存的引用时,无法释放内存,导致内存泄漏:

int& allocateInteger() {int* p = new int(42);return *p;
}

正确的做法是返回指针:

int* allocateInteger() {int* p = new int(42);return p;
}

7. 循环引用

对象之间的循环引用会导致内存泄漏,尤其是在使用智能指针如shared_ptr时。使用weak_ptr可以解决这个问题:

class ClassA {
public:void setInnerPtr(weak_ptr<ClassB> pB) {p = pB;}
private:weak_ptr<ClassB> p;
};class ClassB {
public:void setInnerPtr(weak_ptr<ClassA> pA) {p = pA;}
private:weak_ptr<ClassA> p;
};

8. 野指针和悬挂指针

野指针指向未知或随机地址,而悬挂指针指向已释放的内存,两者都可能导致未定义行为:

int* p1; // 野指针
int* p2 = NULL; // 非野指针
p1 = new int(10); // 非野指针
delete p1; // 悬挂指针

9. 浅拷贝产生悬挂指针

未重写拷贝构造函数和赋值运算符的类,可能导致浅拷贝,从而产生悬挂指针:

class Student {
private:char* mName;
public:// 构造函数、析构函数、拷贝构造函数和赋值运算符...
};

10. 异常安全问题

在异常处理中,如果资源未在所有退出路径上正确释放,可能导致内存泄漏:

try {int* myData = new int[100];// 可能抛出异常delete[] myData;
} catch (...) {// 异常处理
}

11. 隐式内存泄漏

隐式内存泄漏包括内存碎片、内存管理块未归还操作系统、STL内部内存管理策略等,这些都可能导致内存耗尽:

  • 内存碎片:大量小内存块导致无法重新分配。
  • 内存管理块:运行时库可能不归还内存给操作系统。
  • STL内存管理:内存可能不会立即归还操作系统。

相关文章:

C++常见内存泄漏案例分析以及解决方案

C 常见内存泄漏案例分析以及解决方案 1. 分配与释放不匹配 在动态内存管理中&#xff0c;使用new操作符分配的内存必须通过delete操作符显式释放。若未遵循这一规则&#xff0c;将导致内存泄漏。例如&#xff1a; int *p new int; p new int; // 错误&#xff1a;未释放先…...

[LeetCode-Python版]206. 反转链表(迭代+递归两种解法)

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1] 示例 3&#xff1…...

70 mysql 中事务的隔离级别

前言 mysql 隔离级别有四种 未提交读, 已提交读, 可重复度, 序列化执行 然后不同的隔离级别存在不同的问题 未提交读存在 脏读, 不可重复度, 幻觉读 等问题 已提交读存在 不可重复度, 幻觉读 等问题 可重复读存在 幻觉读 等问题 序列化执行 没有以上问题 然后 我们这里…...

C语言二叉树

1.思维导图 树 二叉树 2.将链式队列重新实现一遍 linkqueue.c #include"linkqueue.h" linkqueuePtr create() {linkqueuePtr L(linkqueuePtr)malloc(sizeof(linkqueue));if(NULLL){printf("队列创建失败\n");return NULL;}L->head(nodePtr)malloc(si…...

智能工厂的设计软件 三种处理单元(NPU/GPU/CPU)及其在深度学习框架中的作用 之1

本文要点 深度学习&#xff1a;认知系统架构的处理层 在认知系统架构的设计和代码实现上 需要考虑多个层次&#xff0c;包括感知层、处理层、决策层和执行层。其中 深度学习主要用来解决处理层上的认知问题。 感知层&#xff1a;负责收集外部环境的信息。 处理层&#xff1a;…...

iOS swift开发系列--如何给swiftui内容视图添加背景图片显示

我需要在swiftui项目中显示背景图&#xff0c;有两种方式&#xff0c;一种是把图片拖入asset资源中&#xff0c;另外一种是直接把图片放在源码目录下。采用第一种方式&#xff0c;直接把图片拖到资源目录&#xff0c;但是swiftui项目没有弹出&#xff0c; “Copy items if need…...

jmeter后端监视器

一、概述 JMeter 后端监听器(Backend Listener)是 JMeter 提供的一个功能强大的插件,用于将测试执行期间收集的性能数据发送到外部系统进行监控和分析。通过后端监听器,您可以实时地将 JMeter 测试执行期间收集的数据发送到外部系统,如图形化展示、数据库、数据分析工具等…...

服务器数据恢复—RAIDZ离线硬盘数超过热备盘数导致阵列崩溃的数据恢复案例

服务器存储数据恢复环境&#xff1a; ZFS Storage 7320存储阵列中有32块硬盘。32块硬盘分为4组&#xff0c;每组8块硬盘&#xff0c;共组建了3组RAIDZ&#xff0c;每组raid都配置了热备盘。 服务器存储故障&#xff1a; 服务器存储运行过程中突然崩溃&#xff0c;排除人为误操…...

面试题整理4----lvs,nginx,haproxy区别和使用场景

LVS、Nginx、HAProxy&#xff1a;区别与使用场景 1. LVS&#xff08;Linux Virtual Server&#xff09;1.1 介绍1.2 特点1.3 使用场景 2. Nginx2.1 介绍2.2 特点2.3 使用场景 3. HAProxy3.1 介绍3.2 特点3.3 使用场景 4. 总结对比 在构建高可用、高性能的网络服务时&#xff0c…...

iOS - 超好用的隐私清单修复脚本(持续更新)

文章目录 前言开发环境项目地址下载安装隐私访问报告隐私清单模板最后 前言 在早些时候&#xff0c;提交应用到App Store审核&#xff0c;大家应该都收到过类似这样的邮件&#xff1a; Although submission for App Store review was successful, you may want to correct th…...

html <a>设置发送邮件链接、打电话链接 <a href=“mailto:></a> <a href=“tel:></a>

1.代码 <ul><li>电话&#xff1a;<a href"tel:18888888888">188-8888-8888</a></li><li>邮箱&#xff1a;<a href"mailto:10000qq.com">10000qq.com</a></li><li>邮箱&#xff1a;<a hre…...

clickhouse-副本和分片

1、副本 1.1、概述 集群是副本和分片的基础&#xff0c;它将ClickHouse的服务拓扑由单节点延伸到多个节点&#xff0c;但它并不像Hadoop生态的某些系统那样&#xff0c;要求所有节点组成一个单一的大集群。ClickHouse的集群配置非常灵活&#xff0c;用户既可以将所有节点组成…...

2009 ~ 2019 年 408【计算机网络】大题解析

2009 年 路由算法&#xff08;9’&#xff09; 讲解视频推荐&#xff1a;【BOK408真题讲解-2009年&#xff08;催更就退网版&#xff09;】 某网络拓扑如下图所示&#xff0c;路由器 R1 通过接口 E1 、E2 分别连接局域网 1 、局域网 2 &#xff0c;通过接口 L0 连接路由器 R2 &…...

vue2使用render,js中写html

1、js部分table.js export default {name: "dadeT",data() {return {dades: 6666};},render(h) {return h(div, [h(span, 组件数据&#xff1a;${this.dades}), // 利用data里的dades数据&#xff0c;展示在页面上h(span, 89855545)]);} };2、vue部分 <templat…...

如何有效划分服务器磁盘空间?具体的步骤和流程

有效划分服务器磁盘空间对于提升系统性能、管理方便性和数据安全性至关重要。合理的磁盘分区不仅有助于提高服务器的运行效率&#xff0c;还能在数据恢复、系统故障修复和存储管理方面提供更高的灵活性。以下是如何有效划分服务器磁盘空间的几个关键步骤和注意事项。 磁盘分区的…...

labelme标签批量转换数据集json_to_dataset

文章目录 labelme标签批量转换数据集json_to_dataset转换原理单张图片转换多张图片批量转换bat脚本循环法 标注图片提取标注图片转单通道 labelme标签批量转换数据集json_to_dataset 转自labelme批量制作数据集教程。 转换原理 在安装了labelme的虚拟环境中有一个labelme_js…...

Fisco-Bcos-java-SDK 利用java与fisco-Bcos区块链上的智能合约交互(以HelloWorld为例)

Fisco-Bcos-java-SDK 利用java与fisco-Bcos区块链上的智能合约交互&#xff08;以HelloWorld为例&#xff09; 一、部署智能合约 1、编写智能合约 此处用最简单的HelloWorld合约作为例子 包含两个方法和一个构造函数 构造函数&#xff1a;当合约部署的时候 执行构造函数 将…...

OpenHarmony-3.HDF Display子系统(6)

Display 子系统 1.Display驱动模型介绍 当前操作系统和 SOC 种类繁多&#xff0c;各厂商的显示屏器件也各有不同&#xff0c;随之针对器件的驱动代码也不尽相同&#xff0c;往往是某一款器件驱动&#xff0c;只适用于某单一内核系统或 SOC&#xff0c;如果要迁移到其他内核或者…...

Nginx中Server块配置的详细解析

Nginx中Server块配置的详细解析 一、Server块简介 在Nginx配置文件中&#xff0c;server块是非常关键的部分。它用于定义虚拟主机&#xff0c;一个server块就代表一个虚拟主机。这使得我们可以在一台Nginx服务器上通过不同的配置来处理多个域名或者基于不同端口的服务请求。 …...

php学习资料分享

php学习资料分享&#xff1a;夸克网盘分享...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...