实例演示--vector与内存管理

由于本面问题下面文件尽量做到节省空间
// 测试主文件
    //
 -*- C++ -*-

// =============================================================================
/**
 *  测试目的:vector相关内存泄漏检测
 *  内容简介:
 *  1)测试不同类型的vector
 *  2)对象的构造与析构及内存泄露检测
 *  3)for_each, ostream_iterator,仿函数(函数对象),操作符<<重载
 *  !!!接口中记得加入虚析构函数!!!
*  !!!内存检测 参见:http://blog.csdn.net/dananhai/archive/2007/06/05/1639331.aspx
 
*/

// =============================================================================

#include 
< algorithm >
#include 
< functional >
#include 
< vector >
#include 
< iostream >
#include 
< strstream >
#include 
< string >
using   namespace  std;

#include 
" mydebugnew.h "

#define  OSTREAM cout
// ----------------------------------------------------------------------------
template  < class  _Ty >
struct  mydestroy :  public  unary_function < _Ty,  void >   {
    
void operator()(const _Ty *_X) {
        
if (NULL != _X) { delete _X; _X = NULL;}
    }

}
;

template 
< class  _Ty >
struct  mysum  {
    mysum() : sum_(
0{OSTREAM << "mysum::mysum() this{" << this << "}" << endl;}
    mysum(
const mysum& rhs) : sum_(rhs.sum_) 
        OSTREAM 
<< "mysum::mysum(const mysum&) this{" << this << "}" << endl; 
    }

    
~mysum(){OSTREAM << "mysum::~mysum() this{" << this << "} sum_:" << sum_ << endl;}
    
void operator()(const _Ty &_X) {
        sum_ 
+= _X;
    }

    _Ty sum_;
}
;

class  IMyType  {
public:
    
// !!!接口必须添加虚析构函数,否则无法正确调用实现类析构函数
    virtual ~IMyType() { OSTREAM << "IMyType::~IMyType()" << endl;}
    
virtual void dump(ostream &o) const = 0;
}
;

ostream
&   operator   <<  (ostream  & o,  const  IMyType  & _X)  {
    _X.dump(o); 
return o;
}


ostream
&   operator   <<  (ostream  & o,  const  IMyType  * _X)  {
    
return o << *_X;
}


class  MyType :  public  IMyType
{
public:
    MyType() 
{
        init(); OSTREAM 
<< "MyType::MyType() order{" << *order_ << "}" << endl;
    }

    MyType(
const MyType& rhs) {
        init();
        OSTREAM 
<< "MyType::MyType(const MyType& rhs) order{" << *order_ << "}" << endl;
    }
    
    
~MyType() {
        fini();
        OSTREAM 
<< "MyType::~MyType()" << endl;
    }

    
void dump(ostream &o) const {
        o 
<< "[DUMP] MyType::this={" << static_cast<void*>(const_cast<MyType*>(this)) 
          
<< "}, count_={" << *order_ <<"}"; }

private:
    MyType
& operator=(const MyType &rhs);
    
void init() ++count_; order_ = new int(count_); }
    
void fini() --count_; delete order_;}
    
int *order_;
    
static int count_;
}
;

int  MyType::count_  =   0 ;

// ----------------------------------------------------------------------------
void  int_vector()
{
    vector
<int> vInteger;
    
for (int i = 0; i < 10++i)
        vInteger.push_back(i);
    copy(vInteger.begin(), vInteger.end(), ostream_iterator
<int>(OSTREAM, " "));
    
// !!!编译优化掉一个拷贝构造函数
    mysum<int> fosum = for_each(vInteger.begin(), vInteger.end(), mysum<int>());
    OSTREAM 
<< "sum of <vInteger>=" << fosum.sum_ << endl;
}


// ----------------------------------------------------------------------------
void  string_vector()
{
    vector
<string> vString;
    
for (int ii = 0; ii < 10++ii) {
        strstream sio; sio 
<< "item:" << ii;
        
*(sio.str() + sio.pcount()) = 0;
        vString.push_back(sio.str());
    }

    copy(vString.begin(), vString.end(), ostream_iterator
<string>(OSTREAM, " "));
    OSTREAM 
<< endl;
}


// ----------------------------------------------------------------------------
void  mytype_vector()
{
    
if (0{
        
// !!!注意!!!
        
// 1)观察vector vmyType构造过程
        
// 2)对象元素vector析构函数释放内存后自动调用元素对象的析构函数
        vector<MyType> vmyType(5);
        copy(vmyType.begin(), vmyType.end(), ostream_iterator
<IMyType>(OSTREAM, " "));
    }

    OSTREAM 
<< endl;
    
if (1
        
// !!!注意!!!
        
// 非对象元素(包括对象指针和内建类型)vector析构函数仅释放内存
        vector<IMyType *> vmyTypep;
        
for (int i = 0; i < 5++i) {
            MyType 
*pE = new MyType;
            vmyTypep.push_back(pE);
        }

        copy(vmyTypep.begin(), vmyTypep.end(), ostream_iterator
<IMyType *>(cout, " "));
        
// !!!注意!!!
        
// 1)注释下面代码,观察内存泄漏;
        
// 2)删除IMyType虚析构函数,观察内存泄漏
        for_each(vmyTypep.begin(), vmyTypep.end(), mydestroy<IMyType>());
    }

    OSTREAM 
<< endl;
}


// ----------------------------------------------------------------------------
int  main( int char * [])
{
    REG_DEBUG_NEW;

    int_vector();

    string_vector();

    mytype_vector();

    
return 0;
}

内存检测部分

//  mydebugnew.h
#ifndef __MYDEBUGNEW_H__
#define  __MYDEBUGNEW_H__

#ifdef _DEBUG    

    
#define  _CRTDBG_MAP_ALLOC
    #include 
< stdlib.h >
    #include 
< crtdbg.h >

    
#undef  new
    
extern   void  _RegDebugNew(  void  );
    
extern   void *  __cdecl  operator   new ( size_t,  const   char * int  );
    
extern   void  __cdecl  operator  delete(  void * const   char * int );
    
#define  new new(__FILE__, __LINE__)

    
class  MyDebugNewWrapper
    
{
    
public:
        MyDebugNewWrapper() 
{
            _RegDebugNew();
        }

        
~MyDebugNewWrapper() {
            _CrtDumpMemoryLeaks();
        }

    }
;

    
#define  REG_DEBUG_NEW 
        MyDebugNewWrapper __MyDebugNewWrapper;

#else
    
#define  REG_DEBUG_NEW
#endif

#endif   //  __MYDEBUGNEW_H__

//  mydebugnew.cpp
#ifdef _DEBUG

// #include "mydebugnew.h"
#include  < crtdbg.h >

void  _RegDebugNew(  void  )
{
    _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG 
| _CRTDBG_LEAK_CHECK_DF );
}


void *  __cdecl  operator   new ( size_t nSize,  const   char *  lpszFileName,  int  nLine )
{
    
void* p = _malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine );
    
return p;
}


void  __cdecl  operator  delete(  void *  p,  const   char *   /*lpszFileName*/ int   /*nLine*/  )
{
    _free_dbg( p, _CLIENT_BLOCK );
}


#endif   //  _DEBUG


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值