C++内存泄露排查
内存泄漏是指程序动态分配的内存未能及时释放,导致系统内存逐渐耗尽,最终可能造成程序崩溃或性能下降。在C++中,内存泄漏通常发生在使用new或malloc等分配内存的操作时,但没有正确地使用delete或free来释放这块内存。
在日常开发过程中,为了避免内存泄露,一般都用智能指针去自动管理内存,避免忘记释放。
1.内存泄露动态分析工具——Valgrind
Valgrind是运行在linux上的程序分析工具,它包含很多小工具: memcheck(内存泄露检查工具)等
1.1 安装Valgrind
下载链接:https://valgrind.org/downloads/current.html#current
1.2 Valgrind简单上手和分析
参考:Linux 性能分析valgrind(一)之memcheck使用
命令(以下程序均可以使用此命令):
valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full --show-leak-kinds=all ./your_program
# --log-file: 报告文件名。如果没有指定,输出到stderr
# --tool=memcheck: 指定Valgrind使用的工具,Valgrind是一个工具集,包括Memcheck、Cachegrind、Callgrind等多个工具,memcheck是缺省项。
# --leak-check: 指定如何报告内存泄漏(memcheck能检查多种内存使用错误,内存泄漏是其中常见的一种),可选值有:
# - no 不报告
# - summary 显示简要信息,有多少个内存泄漏。summary是缺省值。
# - yes 和 full 显示每个泄漏的内存在哪里分配。
# --show-leak-kinds: 指定显示内存泄漏的类型的组合。类型包括definite, indirect, possible,reachable。也可以指定all或none。[缺省值](https://www.zhihu.com/search?q=缺省值&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra={"sourceType"%3A"article"%2C"sourceId"%3A92074597})是definite,possible。 运行一段时间后想停止进程不要kill掉,需要ctrl + c来结束,输出的log会在上述命令中的valgrind.log中。
程序1(C程序):使用未初始化的内存
#include <stdio.h>
#include <stdlib.h> int main(void)
{char *p; char c = *p; printf("\n [%c]\n",c); return 0;
}
Valgrind重点结果信息:使用未初始化的变量,无效的读( 读取没有分配地址空间的区域数据 )
==73374== Use of uninitialised value of size 8
==73374== at 0x400513: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
==73374==
==73374== Invalid read of size 1
==73374== at 0x400513: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
==73374== Address 0x0 is not stack'd, malloc'd or (recently) free'd
程序2(C程序):在内存被释放后进行读/写
#include <stdio.h>
#include <stdlib.h> int main(void)
{char *p = malloc(1);*p = 'a'; char c = *p; printf("\n [%c]\n",c); free(p);c = *p;return 0;
}
Valgrind重点结果信息:
==74181== Invalid read of size 1
==74181== at 0x4005E3: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
==74181== Address 0x520a040 is 0 bytes inside a block of size 1 free'd
==74181== at 0x4C3195F: free (vg_replace_malloc.c:872)
==74181== by 0x4005DE: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
==74181== Block was alloc'd at
==74181== at 0x4C2F075: malloc (vg_replace_malloc.c:381)
==74181== by 0x4005A8: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
程序3(C程序): 内存泄露
#include <stdio.h>
#include <stdlib.h> int main(void)
{char *p = malloc(1);*p = 'a'; char c = *p; printf("\n [%c]\n",c); return 0;
}
Valgrind重点结果信息:直接泄露
==74814== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==74814== at 0x4C2F075: malloc (vg_replace_malloc.c:381)
==74814== by 0x400558: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
程序4(C++程序):不匹配使用malloc free 和 new delete
#include <stdio.h>
#include <stdlib.h>
#include<iostream> int main(void)
{char *p = (char*)malloc(1);*p = 'a'; char c = *p; printf("\n [%c]\n",c);delete p;return 0;
}
Valgrind重点结果信息:
==75341== by 0x400683: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
==75341== Address 0x5b20c80 is 0 bytes inside a block of size 1 alloc'd
==75341== at 0x4C2F075: malloc (vg_replace_malloc.c:381)
==75341== by 0x400648: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
程序5(C程序): 两次释放内存
#include <stdio.h>
#include <stdlib.h> int main(void)
{char *p = (char*)malloc(1);*p = 'a'; char c = *p;printf("\n [%c]\n",c);free(p);free(p);return 0;
}
Valgrind重点结果信息:
==76126== Invalid free() / delete / delete[] / realloc()
==76126== at 0x4C3195F: free (vg_replace_malloc.c:872)
==76126== by 0x4005EA: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
==76126== Address 0x520a040 is 0 bytes inside a block of size 1 free'd
==76126== at 0x4C3195F: free (vg_replace_malloc.c:872)
==76126== by 0x4005DE: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
==76126== Block was alloc'd at
==76126== at 0x4C2F075: malloc (vg_replace_malloc.c:381)
==76126== by 0x4005A8: main (in /home/bossdog/3Growup/valgrind/test1/a.exe)
1.3 官方手册
官方手册
2.实际问题分析
struct image_u8
{const int32_t width;const int32_t height;const int32_t stride;uint8_t *buf;
};std::shared_ptr<image_u8> image;image.reset(new image_u8({ frame_out.stFrameInfo.nWidth,frame_out.stFrameInfo.nHeight,frame_out.stFrameInfo.nWidth,new uint8_t[frame_out.stFrameInfo.nWidth * frame_out.stFrameInfo.nHeight * sizeof(uint8_t)] }));image.reset();
std::shared_ptr
会自动管理 image_u8对象的生命周期,但是它不会管理 buf(即 uint8_t*
类型的指针)所指向的内存。
当执行image.reset();
之后,image指针被释放重置了,但是指针所指向的指针即 uint8_t*没有被释放,造成了内存泄露。
记录
- 二级指针被释放时,不会自动释放一级指针中所指向的内存。
参考:https://blog.csdn.net/weixin_44477424/article/details/136417250
相关文章:

C++内存泄露排查
内存泄漏是指程序动态分配的内存未能及时释放,导致系统内存逐渐耗尽,最终可能造成程序崩溃或性能下降。在C中,内存泄漏通常发生在使用new或malloc等分配内存的操作时,但没有正确地使用delete或free来释放这块内存。 在日常开发过程…...
Http 响应状态码 前后端联调
http 响应状态码 :是服务器在处理HTTP请求时返回的状态信息,用于表示请求的处理结果 1xx : 信息性状态码 100 Continue: 服务器已收到请求头部,客户端应继续发送请求体。 101 Switching Protocols : 切换协议。服务器已理解客户端的请求&a…...
48_Lua错误处理
在编写Lua应用时,都可能会遇到不可预见的错误,而错误处理是确保程序稳定性和健壮性的关键环节。有效的错误处理不仅能防止程序崩溃,还能提供有用的反馈信息给开发者或最终用户,从而提高应用程序的质量。本文将详细介绍Lua中的错误处理机制。 1.错误类型 Lua中的错误类型主…...

shell脚本回顾1
1、shell 脚本写出检测 /tmp/size.log 文件如果存在显示它的内容,不存在则创建一个文件将创建时间写入。 一、 ll /tmp/size.log &>/dev/null if [ $? -eq 0 ];then cat /tmp/size.log else touch /tmp/size.log echo date > /tmp/size.log fi二、 if …...

【3】管理无线控制器
1.概述 本文主要介绍AireOS WLC的管理。WLC的管理可以通过CLI和GUI两种方式,而CLI主要分为console接入、telnet以及SSH的登录管理;GUI的管理分为HTTP和HTTPS。 2.CLI的管理 通过console实现的CLI管理这里就单独进行说明了,只要能找到设备的console接口,通过一般的RJ45接…...

SOME/IP 协议详解——服务发现
文章目录 1. Introduction (引言)2. SOME/IP Service Discovery (SOME/IP-SD)2.1 General(概述)2.2 SOME/IP-SD Message Format2.2.1 通用要求2.2.2 SOME/IP-SD Header2.2.3 Entry Format2.2.4 Options Format2.2.4.1 配置选项(Co…...

Flutter:封装ActionSheet 操作菜单
演示效果图 action_sheet_util.dart import package:ducafe_ui_core/ducafe_ui_core.dart; import package:flutter/material.dart; import package:demo/common/index.dart;class ActionSheetUtil {/// 底部操作表/// [context] 上下文/// [title] 标题/// [items] 选项列表 …...

力扣 全排列
回溯经典例题。 题目 通过回溯生成所有可能的排列。每次递归时,选择一个数字,直到选满所有数字,然后记录当前排列,回到上层时移除最后选的数字并继续选择其他未选的数字。每次递归时,在 path 中添加一个新的数字&…...
Golang 设计模式
文章目录 创建型模式简单工厂模式图形接口具体图形类:圆形具体图形类:矩形工厂类定义使用简单工厂模式 抽象工厂模式1. 定义产品接口2. 定义具体产品实现类3. 定义抽象工厂接口4. 定义具体工厂实现类5. 使用抽象工厂创建对象并使用产品 创建者模式1. 定义…...

Matlab 具有周期性分布的死角孔的饱和空气多孔材料的声学特性
本文对直主孔含侧空腔(死角)的饱和空气多孔介质中的声传播进行了理论和数值研究。侧腔位于沿每个主孔周期性间隔的“节点”上。研究了侧向空腔分布中周期性的影响,并单独考虑了紧间隔死角的低频极限。结果表明,吸附系数和透射损失…...
maven 项目怎么指定打包后名字
在 Spring Boot 的 Maven 项目中,你可以通过配置 pom.xml 文件来指定打包后的文件名。具体步骤如下: 打开 pom.xml 文件:找到你的项目根目录下的 pom.xml 文件。 配置 finalName 属性:在 标签下,添加 属性来指定打包后…...

Java Web开发进阶——Spring Boot与Thymeleaf模板引擎
Thymeleaf 是一个现代化的、功能强大的 Java 模板引擎,常用于生成 Web 应用程序的视图。它与 Spring Boot 的集成十分方便,并且提供了丰富的功能,能够帮助开发者实现动态渲染数据、处理表单、页面控制等操作。下面,我们将详细探讨…...

论文笔记(四十七)Diffusion policy: Visuomotor policy learning via action diffusion(下)
Diffusion policy: Visuomotor policy learning via action diffusion(下) 文章概括5. 评估5.1 模拟环境和数据集5.2 评估方法论5.3 关键发现5.4 消融研究 6 真实世界评估6.1 真实世界Push-T任务6.2 杯子翻转任务6.3 酱汁倒入和涂抹任务 7. 实际双臂任务…...

开始使用Panuon开源界面库环境配置并手写VS2019高仿界面
1. Panuon环境配置 1.1. 通过Nuget 安装 Panuon.WPF.UI1.2. xaml引用命名空间1.3. using Panuon.WPF.UI; 2. VS2019 view 2.1. 设置窗体尺寸和title2.2. 添加静态资源 2.2.1. 什么是静态资源 2.3. 主Grid 2.3.1. 盒子模型2.3.2. 嵌套布局 3. 总结 1. Panuon环境配置 1.1. 通…...

新垂直电商的社交传播策略与AI智能名片2+1链动模式S2B2C商城小程序的应用探索
摘要:随着互联网技术的不断进步和电商行业的快速发展,传统电商模式已难以满足消费者日益增长的个性化和多元化需求。新垂直电商在此背景下应运而生,通过精准定位、用户细分以及深度社交传播策略,实现了用户群体的快速裂变与高效营…...

WPS计算机二级•表格函数计算
听说这里是目录哦 函数基础知识 相对绝对混合引用🌪️相对引用绝对引用混合引用 常用求和函数 SUM函数🌦️语法说明 函数快速求 平均数最值⚡平均数最值 实用统计函数 实现高效统计🌀COUNTCOUNTIF 实用文本函数 高效整理数据🌈RIG…...
ESP32S3官方例程如何使用
一、WIFI 找到app_wifi.c文件 wifi_config_t wifi_config; 把上面代码修改为下面代码 wifi_config_t wifi_config { .sta {.ssid DEFAULT_ESP_WIFI_SSID, //WIFI的SSID.password DEFAULT_ESP_WIFI_PASS, //WIFI密码.threshold.authmode WIFI_AUTH_WPA…...
新版 MacOS 无法从 /usr/local/lib 加载动态链接库的解决办法
自己编写的动态链接库在Unix规范下一般位于/usr/local/lib,在2023年及之前的MacOS版本中,直接将动态库安装到该位置即可在程序运行时加载,可是升级MacOS版本后,ld就报错。 错误现象 运行程序,报错 dyld[6376]: Libra…...
【Varnish】:解决 Varnish 7.6 CDN 静态资源缓存失效问题
项目场景: 在一个使用Varnish作为反向代理的Web应用中,我们依赖CDN(内容分发网络)来缓存静态资源(如图片、CSS、JavaScript文件等),以提高全球用户的访问速度并减轻源站服务器的负载。然而&…...

【记录】篡改猴插件下载网页m3u8视频
1.打开浏览器【管理扩展】页面(edge://extensions/),打开开发人员模式 2.Edge浏览器添加篡改猴插件 3.下载需要的脚本 可以从篡改猴首页找下载网站 https://www.tampermonkey.net/scripts.php?localezh_CN 4.安装成功重启浏览器&#x…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

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

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...