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

Valgrind Memcheck 全解析教程:6个程序说明基础内存错误

Valgrind 是一个强大的动态分析框架,其中的 memcheck 工具用于检测 C/C++ 程序中类型不定的内存错误,是基础级内存调试工具的重要选择。

本文将通过 6 段有意义的错误代码,全面讲解 memcheck 的检测原理和输出分析,进而帮助学习者托底基础。


一、memcheck 基本原理

Valgrind 使用一种动态代码插装技术(Dynamic Binary Instrumentation),保留所有内存分配/释放/操作记录,并对每一次访问进行约束性检查:

  • 访问是否在合法范围内
  • 访问的内容是否已被初始化
  • 是否对释放后的地址进行操作
  • 是否对非添配内存调用 free()

二、六种错误结构解析

在这里插入图片描述

1. 堆内存超级读取 + Use-After-Free

char *p = malloc(1);
*p = 'a';
char t = *(p + 1);     // 超级读取
free(p);
*p = 3;               // 释放后写入

Valgrind 输出

  • Invalid read of size 1 表示超级读
  • Invalid write of size 1 表示 Use-After-Free

分析malloc(1) 只有一个 byte,访问 p+1超范围。 free(p) 后再写 *p是释放后操作,是精准级检测值点。


2. 重复释放 (Double Free)

char *p = malloc(1);
*p = 'a';
free(p);
free(p);

Valgrind 输出

  • Invalid free() 指出上一次释放地址

分析: 重复释放将破坏 heap 内部结构,在 glibc 中可能导致 abort(),Valgrind 可精确抓出。


3. 非添配地址释放 (Invalid Free)

char p = 'a';
free(p);

Valgrind 输出

  • Invalid free() 指出试图释放的是 stack 地址

分析p 是一个普通变量,释放非堆内存是第一级的编程错误,Valgrind 可相当精准地检出。


4. 内存泄漏 (Memory Leak)

char *p = malloc(1);
*p = 'a';
// no free

Valgrind 输出

  • definitely lost: 1 bytes in 1 blocks

分析: 程序退出时 heap 中存在未释放内存块,Valgrind 会标记泄漏类型,并可通过 --leak-check=full 查看分配地点。


5. 未初始化内存读取 (Uninitialized Read)

char *p = malloc(1);
char t = *p;
printf("chat t = %c\n", t);
free(p);

Valgrind 输出

  • Conditional jump or move depends on uninitialised value(s)

分析: malloc 分配的内存是随机值,直接读取而未初始化,会导致打印出的内容非确定,Valgrind 较好地检测读操作是否在可信区域内。


6. 释放后读取 (Use-After-Free: Read)

char *p = malloc(1);
*p = 'a';
free(p);
char t = *p;     // 释放后读
printf("chat t = %c\n", t);

Valgrind 输出

  • Invalid read of size 1

分析: 释放后内存地址成为无效,再读取就是 Use-After-Free 错误,尽管访问成功,结果也是未知行为。


结论

valgrind --tool=memcheck 是分析程序内存问题的重要工具:

  • 它能检测 heap 区间的超级、未初始化、释放错误;
  • 较难检测 stack 超级或静态区超级;
  • 通过精确输出并配合 --track-origins=yes,可相当精精确确地保障基础级 C 编程的内存健康。
http://www.xdnf.cn/news/15990.html

相关文章:

  • SpringBoot的介绍和项目搭建
  • 基于有监督学习的主动攻击检测系统
  • Vision Transformer (ViT) 介绍
  • 以“融合进化 智领未来”之名,金仓Kingbase FlySync:国产数据库技术的突破与创新
  • Redis 概率型数据结构实战指南
  • C++ STL中迭代器学习笔记
  • Docker实践:使用Docker部署WhoDB开源轻量级数据库管理工具
  • AI大模型学习路线-全技术栈
  • HTML和CSS快速入门
  • Spring之AOP面向切面编程详解
  • 试用SAP BTP 06:AI服务-Data Attribute Recommendation
  • 数据结构-线性表顺序表示
  • 基于单片机无线防丢/儿童防丢报警器
  • RabbitMQ:解锁高效消息传递的密码[特殊字符]
  • playwright 最佳实践
  • 【web安全】SQL注入与认证绕过
  • MPLS-LDP
  • 小红书 MCP 服务器
  • ADC和DMA简述
  • 渗透笔记(XSS跨站脚本攻击)
  • Linux之dpkg--命令的用法
  • 软件测试-Bug
  • 41.FeignClient整合Sentinel
  • 【C++】C++入门
  • 氛围编码(Vice Coding)的工具选择方式
  • [CVPR]DVFL-Net:用于时空动作识别的轻量级蒸馏视频调焦网络
  • 华为开源自研AI框架昇思MindSpore应用案例:基于ERNIE模型实现对话情绪识别
  • Spring 事务和事务传播机制
  • CSS 单位完全指南:掌握 em、rem、vh、vw 等响应式布局核心单位
  • 仙盟数据库应用-外贸标签打印系统 前端数据库-V8--毕业论文-—-—仙盟创梦IDE