C/C++程序调试和内存检测
程序出现错误很正常,一个优秀的程序员必须学会调试,发现错误并改正。减少程序错误最有效的方法是:在敲代码之前,多花点时间思考,如何构造程序,数据结构和算法,尽量把细节提前写下来,可以尝试着在纸上写出核心代码,这样可以减少今后修改代码的时间。
1.常用的调试技巧
(1)代码检查,重新阅读程序,排除比较明显的错误。编译时带上-Wall参数,生成所有的警告信息。
gcc -Wall -pedantic -ansi 表示以ansi/iso生成所有的警告西信息。
(2)取样法:在程序中增加一些代码,收集更多与程序运行时的行为相关的信息。使用条件编译,可以清楚的辨别哪些是调试代码,有利于调试后的代码整理。
例如:
#ifdef DEBUG
std::cout << x :
#endif
程序编译时可以选择性的加上-DDEBUG。如果加上这个标志,就定义了DEBUG这个符号,从而在程序中包含调试用的额外代码,没有加上该标志,这些调试代码将删除。
(3)程序的受控执行。用调试器来控制代码的运行,随时查看这些变量的状态。
为了能够调试程序,需要在编译和链接时为每个源文件加上编译选项参数。这些选项的作用是让编译器在程序中添加额外的调试信息。这些信息包括符号和源代码行号,调试器将利用这些信息向用户显示程序已经执行到的源代码的位置。-g标志是对程序调试性编译时常用的一个选项。调试信息的加入使可执行程序的长度成倍的增长、容量增加,程序运行时的内存数量还是和原来一样,程序调试结束后,最好还是将调试信息从程序的发行版中删除。
2.使用gdb进行程序调试
常用功能命令:
g++ -g -o test test.cpp //编译时加上-g参数
- 启动gdb: gdb test
- help
- 具备带有历史记录的命令行编辑功能,方向键选择之前执行过的命令,直接回车键再次执行最近执行过的那条命令。单步调试非常有用。
- quit:退出
- .run:执行这个程序,程序运行失败时gdb会报告失败的原因和位置。
- backtrace(bt):栈跟踪,失败时停止的位置,帮助我们找到程序到达错误地点的路径。
- print:run 后检查变量,注意变量的生命期。
- 打印围绕当前位置前后的一段代码,继续使用list可以显示更多的代码。
- 设置断点,停止程序的运行,查看变量。help breakpoint,break lineNumber,cont,end,display,disable breakpoint number,clear,commands breakpointNumber.
- 设置断点后经常使用单步调试命令next(n),查看程序运行的细节。
3.valgrind内存调试
动态内存分配很容易出现程序漏洞,必须清楚自己分配的每一块内存,而且要确定没有使用已经释放的内存块,非常重要。内存调试的工具有很多,这里使用的是valgrind工具。在centos 7中直接使用 yum install valgrind 安装。
#include <iostream> int main()
{
int *ptr = new int [];
ptr[]=; delete [] ptr;
std::cout << ptr[];
return ;
}
上面简单的代码编译运行不会发生错误,但是实际上发生了很严重的内存问题。ptr[3]访问越界,std::cout <<ptr[i],读已经释放过的内存。
通过valgrind工具可以检查出来:
[xgwang@localhost Desktop]$ g++ -g -o test2 test2.cpp
[xgwang@localhost Desktop]$ valgrind ./test2
==21739== Memcheck, a memory error detector
==21739== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==21739== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==21739== Command: ./test2
==21739==
==21739== Invalid write of size 4
==21739== at 0x40081E: main (test2.cpp:8)
==21739== Address 0x5a1504c is 0 bytes after a block of size 12 alloc'd
==21739== at 0x4C2A7AA: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==21739== by 0x400811: main (test2.cpp:7)
==21739==
==21739== Invalid read of size 4
==21739== at 0x40083F: main (test2.cpp:11)
==21739== Address 0x5a15044 is 4 bytes inside a block of size 12 free'd
==21739== at 0x4C2B5E1: operator delete[](void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==21739== by 0x400836: main (test2.cpp:10)
==21739==
0==21739==
==21739== HEAP SUMMARY:
==21739== in use at exit: 0 bytes in 0 blocks
==21739== total heap usage: 1 allocs, 1 frees, 12 bytes allocated
==21739==
==21739== All heap blocks were freed -- no leaks are possible
==21739==
==21739== For counts of detected and suppressed errors, rerun with: -v
==21739== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
C/C++程序调试和内存检测的更多相关文章
- VC使用CRT调试功能来检测内存泄漏
信息来源:csdn C/C++ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:“最大的长处也可能成为最大的弱点”,那么 C/C++ 应用程序正好印证了这句话.在 C/C+ ...
- 【调试】Linux下超强内存检测工具Valgrind
[调试]Linux下超强内存检测工具Valgrind 内容简介 Valgrind是什么? Valgrind的使用 Valgrind详细教程 1. Valgrind是什么? Valgrind是一套Lin ...
- [Swift通天遁地]七、数据与安全-(11)如何检测应用程序中的内存泄露
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- .NET应用程序调试—原理、工具、方法
阅读目录: 1.背景介绍 2.基本原理(Windows调试工具箱..NET调试扩展SOS.DLL.SOSEX.DLL) 2.1.Windows调试工具箱 2.2..NET调试扩展包,SOS.DLL.S ...
- iOS Instruments内存检测使用
Instruments 可以帮我们了解到应用程序使用内存的几个方面: 全局内存使用情况(Overall Memory Use): 从全局的角度监测应用程序的内存使用情况,捕捉非预期的或大幅度的内存增长 ...
- Keil 程序调试窗口
上一讲中我们学习了几种常用的程序调试方法,这一讲中将介绍Keil提供各种窗口如输出窗口.观察窗口.存储器窗口.反汇编窗口.串行窗口等的用途,以及这些窗口的使用方法,并通过实例介绍这些窗口在调试中的使用 ...
- C++雾中风景番外篇3:GDB与Valgrind ,调试代码内存的工具
写 C++的同学想必有太多和内存打交道的血泪经验了,常常被 C++的内存问题搅的焦头烂额.(写 core 的经验了)有很多同学一见到 core 就两眼一抹黑,不知所措了.笔者 入"坑&quo ...
- 基于链表的C语言堆内存检测
说明 本文基于链表实现C语言堆内存的检测机制,可检测内存泄露.越界和重复释放等操作问题. 本文仅提供即视代码层面的检测机制,不考虑编译链接级的注入或钩子.此外,该机制暂未考虑并发保护. 相关性文章参见 ...
- 嵌入式linux应用程序调试方法
嵌入式linux应用程序调试方法 四 内存工具 五 C/C++代码覆盖.性能profiling工具 四 内存工具 您肯定不想陷入类似在几千次调用之后发生分配溢出这样的情形. 许多小组花了许许多多时间来 ...
随机推荐
- spring mvc静态资源请求和<mvc:annotation-driven>
自己看了官方文档,也到网上查了下,目前理解如下: <mvc:annotation-driven/>相当于注册了DefaultAnnotationHandlerMapping和Annotat ...
- LeetCode144:Binary Tree Preorder Traversal
题目: Given a binary tree, return the preorder traversal of its nodes' values. For example: Given bina ...
- Spring Boot 2 实践记录之 Powermock 和 SpringBootTest
由于要代码中使用了 Date 类生成实时时间,单元测试中需要 Mock Date 的构造方法,以预设其行为,这就要使用到 PowerMock 在 Spring Boot 的测试套件中,需要添加 @Ru ...
- ==和Equals与值类型和引用类型
==和Equals 对于值类型来说判断的是值,对于引用类型来说判断的是堆地址 注意:string 是引用类型(也可看做只读char[]数组)(字符串的不可变性·拘留池)特殊的值类型(使用==.Equa ...
- C#一些代码小结--文件对话框
C# 一些代码小结--文件对话框 查看文件完整路径 try { Config cfg = new Config(); var file = ""; if (saveFileDial ...
- VS未能正确加载 ”Microsoft.VisualStudio.Editor.Implementation.EditorPackate“包错误解决方法
很久没用VS了,打开后出现未能正确加载 ”Microsoft.VisualStudio.Editor.Implementation.EditorPackate“包的错误,经过一番上网查阅错误得以解决. ...
- AtomicInteger源码解析
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.原子类 可以实现一些原子操作 基于CAS 下面就以AtomicInteger为例. 2.AtomicIn ...
- IPv6 Scapy Samples
IPv6 ICMP icmp ipv6 request i=IPv6() i.dst="2001:db8:dead::1" q=ICMPv6EchoRequest() p=(i/q ...
- Cordova - 实现热更新 !
Cordova版本:8.0.0 更新APP平台:Android 操作系统:Windows Cordova的热更新,作用是把www内的变动部分更新到APP中,实现主程序不动,完成更新!!这个热更新功能, ...
- Mac OS 10.12 - 如何关闭Rootless机制?
一,进入恢复模式(Recovery):具体操作方法参见下面这篇博客: http://www.cnblogs.com/sunylat/p/6414697.html 二,关闭Rootless机制 1,选择 ...