C++ 复制控制 Copy Control 示例, 及内存泄漏检测工具 Valgrind 的简单使用

主页: http://valgrind.org/

文档下载:http://valgrind.org/docs/download_docs.html

简单使用:  http://cs.ecs.baylor.edu/~donahoo/tools/valgrind/

valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./test

Valgrind is an instrumentation framework for building dynamic analysis tools. There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail. You can also use Valgrind to build new tools.

The Valgrind distribution currently includes six production-quality tools: a memory error detector, two thread error detectors, a cache and branch-prediction profiler, a call-graph generating cache and branch-prediction profiler, and a heap profiler. It also includes three experimental tools: a heap/stack/global array overrun detector, a second heap profiler that examines how heap blocks are used, and a SimPoint basic block vector generator. It runs on the following platforms: X86/Linux, AMD64/Linux, ARM/Linux, PPC32/Linux, PPC64/Linux, S390X/Linux, MIPS/Linux, ARM/Android (2.3.x and later), X86/Android (4.0 and later), X86/Darwin and AMD64/Darwin (Mac OS X 10.6 and 10.7, with limited support for 10.8).

当源代码使用 -g 选项编时,valgrind 可以定位出现内存泄漏的行号, 无-g选项也是可以的。

如:  g++ -g HasPtr.cxx

 

/*
 * HasPtr.cxx
 * 
 */
#include <iostream>
using namespace std;

class HasPtr{
public:
	//默认构造函数
	HasPtr(){
		cout<<"HasPtr默认构造函数被调用"<<hex<<this<<dec<<endl;
		//pval = new int(0); //#1
		pval = NULL;
		val = 0;
	}
	//正常构造函数
	HasPtr(const int * rhs,int ival = 0){
		cout<<"HasPtr构造函数被调用,this@"<<hex<<this<<dec<<endl;
		pval = new int(*rhs);
		val = ival;
	}
	//复制构造函数
	HasPtr(const HasPtr & rhs){
		cout<<"HasPtr复制构造函数被调用,this@"<<hex<<this<<dec<<endl;
		pval = new int(*rhs.pval);
		val = rhs.val;
	}
	//赋值操作符
	HasPtr &  operator = (const HasPtr & rhs){
		cout<<"HasPtr operator = 函数被调用,this@"<<hex<<this<<dec<<endl;
		//*pval = *rhs.pval;	//#1处,在默认构造中也有分配指针所指对象,则直接赋值
		
		/***************************************************/
		delete pval;			//删除NULL指针是安全的,注释掉这行,可以查看到内存泄漏
		/***************************************************/
		
		pval = new int(*rhs.pval);
		val = rhs.val;
		return *this;
	}
	
	//构造函数
	~HasPtr(){
		delete pval;
		cout<<"HasPtr析造函数被调用,this@"<<hex<<this<<dec<<endl;
	}
	
	void to_str(){
		cout<<"HasPtr.to_str() called:val="<<val
		<<",*pval="<<*pval
		<<",pval="<<hex<<pval<<
		",this@"<<hex<<this<<dec<<endl<<endl;
	}
//private:
	int val,*pval;
};

int main(int argc, char **argv)
{
	int i =110;
	HasPtr p1(&i,2);
	p1.to_str();
	
	//HasPtr p2(&i,2);	//常规构造函数
	//HasPtr p2(p1);	//复制构造函数
	//HasPtr p2 = p1;	//复制构造函数
	
	HasPtr p2;			//默认构造
	p2 = p1;			//赋值操作符
	
	p2.to_str();
	
	p2.val *=2;
	*p2.pval *=2;
	
	cout<<"########## after change ##########"<<endl;
	p1.to_str();
	p2.to_str();
	
	p1 = p2;
	cout<<"######## p1 = p2 ############"<<endl;
	
	p1.to_str();
	p2.to_str();
	return 0;
}

 

检测结如下:

spark@spark-vbox:~/workspace/Cpp$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./a.out
==5837== Memcheck, a memory error detector
==5837== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5837== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5837== Command: ./a.out
==5837== 
HasPtr构造函数被调用,this@0xbee6204c
HasPtr.to_str() called:val=2,*pval=110,pval=0x4323028,this@0xbee6204c

HasPtr默认构造函数被调用0xbee62054
HasPtr operator = 函数被调用,this@0xbee62054
HasPtr.to_str() called:val=2,*pval=110,pval=0x4323060,this@0xbee62054

########## after change ##########
HasPtr.to_str() called:val=2,*pval=110,pval=0x4323028,this@0xbee6204c

HasPtr.to_str() called:val=4,*pval=220,pval=0x4323060,this@0xbee62054

HasPtr operator = 函数被调用,this@0xbee6204c
######## p1 = p2 ############
HasPtr.to_str() called:val=4,*pval=220,pval=0x4323098,this@0xbee6204c

HasPtr.to_str() called:val=4,*pval=220,pval=0x4323060,this@0xbee62054

HasPtr析造函数被调用,this@0xbee62054
HasPtr析造函数被调用,this@0xbee6204c
==5837== 
==5837== FILE DESCRIPTORS: 3 open at exit.
==5837== Open file descriptor 2: /dev/pts/2
==5837==    <inherited from parent>
==5837== 
==5837== Open file descriptor 1: /dev/pts/2
==5837==    <inherited from parent>
==5837== 
==5837== Open file descriptor 0: /dev/pts/2
==5837==    <inherited from parent>
==5837== 
==5837== 
==5837== HEAP SUMMARY:
==5837==     in use at exit: 4 bytes in 1 blocks
==5837==   total heap usage: 3 allocs, 2 frees, 12 bytes allocated
==5837== 
==5837== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==5837==    at 0x402B9B4: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5837==    by 0x8048B86: HasPtr::HasPtr(int const*, int) (HasPtr.cxx:20)
==5837==    by 0x8048821: main (HasPtr.cxx:58)
==5837== 
==5837== LEAK SUMMARY:
==5837==    definitely lost: 4 bytes in 1 blocks
==5837==    indirectly lost: 0 bytes in 0 blocks
==5837==      possibly lost: 0 bytes in 0 blocks
==5837==    still reachable: 0 bytes in 0 blocks
==5837==         suppressed: 0 bytes in 0 blocks
==5837== 
==5837== For counts of detected and suppressed errors, rerun with: -v
==5837== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

 它可以检测出在哪一行分配的内存没有被释放,不能给出合适的应该释放的位置,这确实难办到,分析时要注意。

原文链接: https://www.cnblogs.com/wucg/archive/2013/05/16/3082160.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++ 复制控制 Copy Control 示例, 及内存泄漏检测工具 Valgrind 的简单使用

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/88733

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午11:46
下一篇 2023年2月9日 下午11:47

相关推荐