由于本面问题下面文件尽量做到节省空间
// 测试主文件
// -*- 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
// 测试主文件// -*- 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
本文通过测试不同类型的C++标准库vector,展示了如何检测内存泄漏,并深入探讨了对象的构造与析构,以及如何使用for_each和ostream_iterator进行迭代操作。特别关注了对象指针在vector中的内存管理。


1616

被折叠的 条评论
为什么被折叠?



