分享
 
 
 

灵巧指针与垃圾回收源代码

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

本人将源代码粘贴于此,各位有兴趣的网友可以测试一试。

说明:

只要将两个文件加入到你的工程中,并在你的CWinApp派生类中加入如下一句即可:

CPtrManager thePtrManager;

然后,在使用普通指针的地方,用灵巧指针替换即可,假如有一个类test,并有如下应用:

test * ptest=new test;

other code

delete ptest;

现在可这样应用:

auto_ptr<test> ptest= new test;

other code

再不用人为的delete ptest 了,垃圾回收将自动清除,即使你有如下应用:

auto_ptr<test> ptest;

test mytest;

ptest=&mytest;

你也不用担心,灵巧指针也不会误删你在栈中的内存。

只要大家认真帮我测试这段代码到没有 BUG,并对部分算法进行优化和改进,那么,我可以相信:“C++中无垃圾回收”将成为历史。

// PtrManager.h: interface for the CPtrManager class.

//

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_PTRMANAGER_H__BB4B38B5_DA34_11D3_9327_000629377185__INCLUDED_)

#define AFX_PTRMANAGER_H__BB4B38B5_DA34_11D3_9327_000629377185__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include "Afxmt.h"

class CMySingleLock:public CSingleLock

{

public:

CMySingleLock(CSyncObject* pObject, BOOL bInitialLock = FALSE )

:CSingleLock(pObject,bInitialLock){}

void operator delete(void * p)

{

free(p);

}

void * operator new(size_t size)

{

return malloc(size);

}

};

class CPtr

{

friend class CMark;

public:

int GetPtrSize();

CMutex * GetCMutex();

void * GetPtr();

CPtr();

virtual ~CPtr();

int GetCount();

void AddAutoPtr(void * autoPtr,int AutoMark);

BOOL DeleteAutoPtr(void * autoPtr);

void SetPtr(void * thePtr,int Size,

int mark,int count=0);

void operator delete(void * p)

{

free(p);

}

void * operator new(size_t size)

{

return malloc(size);

}

private:

int m_mark;

int m_count;

void * m_ptr;

int m_size;

CPtrArray AutoPtrArray;

CUIntArray m_AutoMark; file://0 in the stack; >0 =mark

CMutex mutex;

};

class CMark

{

friend class CMarkTable;

public:

CMark(){}

virtual ~CMark(){}

void operator delete(void * p)

{

free(p);

}

void * operator new(size_t size)

{

return malloc(size);

}

void CopyFromCPtr(CPtr* theCPtr);

BOOL bIsNoneInStack();

void Release();

private:

int m_mark;

CPtrArray autoptrArray;

CUIntArray automarkArray;

};

class CMarkTable

{

public:

CMarkTable(){Init();}

virtual ~CMarkTable(){}

void AddCMark(CMark * theCMark);

BOOL FindMark(int mark);

void Init();

void DoLockMark();

private:

CPtrArray CMarkArray;

CPtrArray CLockMarkArray;

void GetLockMark();

BOOL FindLockMark(int mark);

void RemoveUnlockMark();

void RemoveGroup(int automark);

};

class CPtrManager

{

public:

int GetAutoMark(void * ptr);

CPtrManager();

virtual ~CPtrManager();

int GetMarkFromPtr(void * Ptr);

void *MallocPtr(size_t size);

BOOL bCanWrite();

void DeletePtr(int mark,void * Ptr);

void AddPtr(void *Ptr,int PtrSize);

static CPtrManager * GetPtrManager();

CPtr * GetCPtr(void * Ptr,int mark);

private:

CPtrArray m_ptr;

void* pCurrent;

unsigned int m_mark;

CUIntArray m_removed;

BOOL bWrite;

static CPtrManager * p_this;

CMutex mutex;

CMarkTable myMarkTable;

void RemoveLockRes();

void CopyAllMark();

static UINT myThreadProc(LPVOID lparm);

CWinThread* myThread;

void BeginThread()

{ myThread=AfxBeginThread(myThreadProc,this);}

};

class parent_autoptr

{

public:

parent_autoptr()

{thisAutoMark=0;}

virtual ~parent_autoptr(){}

virtual void Release(){}

protected:

int thisAutoMark;

};

template<class T>

class auto_ptr :public parent_autoptr

{

public:

virtual void Release(){Remove();}

auto_ptr()

{mark=0;pointee=0;thisAutoMark=GetAutoMark();}

auto_ptr(auto_ptr<T>&rhs);

auto_ptr(T*ptr);

~auto_ptr(){Remove();}

T*operator->() const;

operator T*();

T&operator*()const;

auto_ptr<T>&operator=(auto_ptr<T>&rhs);

auto_ptr<T>&operator=(T*ptr);

private:

void Remove();

int GetAutoMark();

CMutex *GetCMutex();

void ReadyWrite();

T*pointee;

int mark;

};

template<class T> T* auto_ptr< T>::operator ->()const

{

return pointee;

}

template<class T> void auto_ptr< T>::ReadyWrite()

{

CPtrManager * pMana=CPtrManager::GetPtrManager();

if(pMana)

{

for(;;)

{

if(pMana->bCanWrite())

break;

}

}

}

template<class T> int auto_ptr< T>::GetAutoMark()

{

CPtrManager * pMana=CPtrManager::GetPtrManager();

if(pMana)

{

return pMana->GetAutoMark(this);

}

return 0;

}

template<class T> CMutex* auto_ptr< T>::GetCMutex()

{

CPtrManager * pMana=CPtrManager::GetPtrManager();

if(pMana)

{

CPtr * theCPtr=pMana->GetCPtr(pointee,mark);

if(theCPtr)

return theCPtr->GetCMutex();

}

return NULL;

}

template<class T> void auto_ptr< T>::Remove()

{

CMutex * theMutex=GetCMutex();

if(theMutex)

{

CMySingleLock *pLock=new CMySingleLock(theMutex);

pLock->Lock();

BOOL bDeleteLock=FALSE;

CPtrManager * pMana=CPtrManager::GetPtrManager();

if(pointee&&pMana)

{

CPtr * theCPtr=pMana->GetCPtr(pointee,mark);

if(theCPtr)

{

if(theCPtr->DeleteAutoPtr(this))

{

if(theCPtr->GetCount()==0)

{

pLock->Unlock();

delete pLock;

pMana->DeletePtr(mark,pointee);

bDeleteLock=TRUE;

delete pointee;

}

}

}

else

{

file://User decide to do

}

}

pointee=NULL;

mark=0;

if(!bDeleteLock)

delete pLock;

}

}

template<class T> auto_ptr< T>::operator T*()

{

return pointee;

}

template<class T> T& auto_ptr< T>::operator *()const

{

return *pointee;

}

template<class T> auto_ptr< T>::auto_ptr(auto_ptr<T>&rhs)

{

thisAutoMark=GetAutoMark();

ReadyWrite();

CMutex * theMutex=GetCMutex();

if(theMutex)

{

CSingleLock singleLock(theMutex);

singleLock.Lock();

pointee=rhs.pointee;

mark=rhs.mark;

CPtrManager * pMana=CPtrManager::GetPtrManager();

if(pMana)

{

CPtr* theCPtr=pMana->GetCPtr(pointee,mark);

if(theCPtr)

{

theCPtr->AddAutoPtr(this,thisAutoMark);

}

}

}

}

template<class T> auto_ptr< T>::auto_ptr(T*ptr)

{

thisAutoMark=GetAutoMark();

ReadyWrite();

mark=0;

pointee=ptr;

CPtrManager * pMana=CPtrManager::GetPtrManager();

if(pMana)

{

mark=pMana->GetMarkFromPtr(ptr);

if(mark>0)

{

CPtr* theCPtr=pMana->GetCPtr(pointee,mark);

if(theCPtr)

{

CMutex * theMutex=theCPtr->GetCMutex();

if(theMutex)

{

CSingleLock singleLock(theMutex);

singleLock.Lock();

theCPtr->AddAutoPtr(this,thisAutoMark);

}

}

}

}

}

template<class T>auto_ptr<T>& auto_ptr< T>::operator=(auto_ptr<T>&rhs)

{

if(pointee!=rhs.pointee)

{

ReadyWrite();

Remove();

pointee=rhs.pointee;

mark=rhs.mark;

CMutex * theMutex=GetCMutex();

if(theMutex)

{

CSingleLock singleLock(theMutex);

singleLock.Lock();

CPtrManager * pMana=CPtrManager::GetPtrManager();

if(pMana)

{

CPtr* theCPtr=pMana->GetCPtr(pointee,mark);

if(theCPtr)

{

theCPtr->AddAutoPtr(this,thisAutoMark);

}

}

}

}

return *this;

}

template<class T> auto_ptr<T>&auto_ptr< T>::operator = (T* ptr)

{

if(pointee!=ptr)

{

ReadyWrite();

Remove();

pointee=ptr;

CPtrManager * pMana=CPtrManager::GetPtrManager();

if(pMana)

{

mark=pMana->GetMarkFromPtr(ptr);

if(mark>0)

{

CPtr* theCPtr=pMana->GetCPtr(pointee,mark);

if(theCPtr)

{

CMutex * theMutex=theCPtr->GetCMutex();

if(theMutex)

{

CSingleLock singleLock(theMutex);

singleLock.Lock();

theCPtr->AddAutoPtr(this,thisAutoMark);

}

}

}

}

}

return *this;

}

class test

{

public:

auto_ptr<test> p;

};

#endif // !defined(AFX_PTRMANAGER_H__BB4B38B5_DA34_11D3_9327_000629377185__INCLUDED_)

// PtrManager.cpp: implementation of the CPtrManager class.

//

//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "PtrManager.h"

CPtrManager * CPtrManager::p_this=0;

void operator delete(void * p)

{

free(p);

}

void * operator new(size_t size)

{

CPtrManager * pMana=CPtrManager::GetPtrManager();

return pMana->MallocPtr(size);

}

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

CPtr::CPtr()

{

m_count=0;

m_mark=0;

m_ptr=0;

m_size=0;

AutoPtrArray.SetSize(0);

m_AutoMark.SetSize(0);

}

CPtr::~CPtr()

{

}

void * CPtr::GetPtr()

{

return m_ptr;

}

void CPtr::AddAutoPtr(void * autoPtr,int AutoMark)

{

int size=AutoPtrArray.GetSize();

AutoPtrArray.SetAtGrow(size,autoPtr);

m_AutoMark.SetAtGrow(size,AutoMark);

m_count++;

}

BOOL CPtr::DeleteAutoPtr(void * autoPtr)

{

int size=AutoPtrArray.GetSize();

for(int i=0;i<size;i++)

{

if(autoPtr==AutoPtrArray[i])

{

AutoPtrArray.RemoveAt(i);

m_AutoMark.RemoveAt(i);

m_count--;

return TRUE;

}

}

return FALSE;

}

int CPtr::GetCount()

{

return m_count;

}

void CPtr::SetPtr(void * thePtr,int Size,int mark,int count)

{

m_ptr=thePtr;

m_mark=mark;

m_size=Size;

m_count=count;

}

CMutex * CPtr::GetCMutex()

{

return &mutex;

}

int CPtr::GetPtrSize()

{

return m_size;

}

// class CPtrManager

CPtrManager::CPtrManager()

{

m_mark=0;

m_ptr.SetSize(1);

m_ptr[0]=0;

m_removed.SetSize(0);

p_this=this;

pCurrent=0;

bWrite=TRUE;

myThread=0;

BeginThread();

}

CPtrManager::~CPtrManager()

{

p_this=0;

if(myThread)

myThread->SuspendThread( );

int size=m_ptr.GetSize();

for(int i=1;i<size;i++)

{

if(m_ptr[i])

{

free(m_ptr[i]);

}

}

}

void CPtrManager::AddPtr(void *Ptr,int PtrSize)

{

CSingleLock singleLock(&mutex);

singleLock.Lock();

int size=0;

if(m_removed.GetSize()==0)

{

size =m_ptr.GetSize();

}

else

{

size=m_removed[0];

m_removed.RemoveAt(0);

}

if(size==0)

size=1;

CPtr * thePtr=new CPtr;

thePtr->SetPtr(Ptr,PtrSize,size);

m_ptr.SetAtGrow(size,thePtr);

pCurrent=Ptr;

m_mark=size;

}

void * CPtrManager::MallocPtr(size_t size)

{

CSingleLock singleLock(&mutex);

singleLock.Lock();

void * p=malloc(size);

if(p)

AddPtr(p,size);

return p;

}

void CPtrManager::DeletePtr(int mark,void*Ptr)

{

if(mark<=0||m_ptr.GetSize()<mark+1)

return ;

CSingleLock singleLock(&mutex);

singleLock.Lock();

if(m_ptr[mark])

{

CPtr * thePtr=(CPtr*)m_ptr[mark];

if(Ptr!=thePtr->GetPtr())

return ;

delete thePtr;

m_ptr[mark]=NULL;

m_removed.Add(mark);

}

}

int CPtrManager::GetMarkFromPtr(void * Ptr)

{

CSingleLock singleLock(&mutex);

singleLock.Lock();

if(pCurrent==Ptr)

return m_mark;

int size=m_ptr.GetSize();

for(int i=1;i<size;i++)

{

if(m_ptr[i]==Ptr)

return i;

}

return NULL;

}

CPtrManager * CPtrManager::GetPtrManager()

{

return p_this;

}

BOOL CPtrManager::bCanWrite()

{

return bWrite;

}

CPtr * CPtrManager::GetCPtr(void * Ptr,int mark)

{

if(!Ptr||mark<=0 || m_ptr.GetSize()<mark+1)

return NULL;

CSingleLock singleLock(&mutex);

singleLock.Lock();

if(m_ptr[mark])

{

CPtr * thePtr=(CPtr*)m_ptr[mark];

if(Ptr!=thePtr->GetPtr())

return NULL;

else

return thePtr;

}

return NULL;

}

int CPtrManager::GetAutoMark(void *ptr)

{

CSingleLock singleLock(&mutex);

singleLock.Lock();

int size =m_ptr.GetSize();

for(int i=1;i<size;i++)

{

CPtr* theCPtr=(CPtr*)m_ptr[i];

if(theCPtr)

{

int ptrFirst=(int)theCPtr->GetPtr();

int ptrEnd=ptrFirst+theCPtr->GetPtrSize();

int p=(int)ptr;

if(p>=ptrFirst&&p<=ptrEnd)

return i;

}

}

return 0;

}

void CPtrManager::RemoveLockRes()

{

CopyAllMark();

myMarkTable.DoLockMark();

}

void CPtrManager::CopyAllMark()

{

CSingleLock singleLock(&mutex);

singleLock.Lock();

CUIntArray theIntArray;

theIntArray.SetSize(0);

int size=m_ptr.GetSize();

for(int i=0;i<size-1;i++)

{

theIntArray.SetAtGrow(i,i+1);

}

bWrite=FALSE;

BOOL bALLCopyed=TRUE;

int TotalWhile=0;

do

{

TotalWhile++;

bALLCopyed=TRUE;

size=theIntArray.GetSize();

for(i=0;i<size;i++)

{

int m=theIntArray[i];

CPtr * theCPtr=(CPtr*)m_ptr[m];

if(theCPtr)

{

CMutex * theMutex;

theMutex=theCPtr->GetCMutex();

if(theMutex)

{

CMySingleLock * theLock;

theLock=new CMySingleLock(theMutex);

if(!theLock->IsLocked())

{

if(theLock->Lock(50))

{

CMark * theMark;

theMark=new CMark();

theMark->CopyFromCPtr(theCPtr);

delete theLock;

myMarkTable.AddCMark(theMark);

theIntArray.RemoveAt(i);

i--;

size--;

}

else

{

delete theLock;

bALLCopyed=FALSE;

}

}

else

{

delete theLock;

bALLCopyed=FALSE;

}

}

}

}

if(TotalWhile>=50)

break;

}while(!bALLCopyed);

bWrite=TRUE;

}

UINT CPtrManager::myThreadProc(LPVOID lparm)

{

CPtrManager* pana=(CPtrManager*)lparm;

if(!pana)

return 0;

Sleep(500);

for(;;)

pana->RemoveLockRes();

return 0;

}

file://begin class CMark

void CMark::CopyFromCPtr(CPtr *theCPtr)

{

if(!theCPtr)

return;

int size=(theCPtr->AutoPtrArray).GetSize();

automarkArray.SetSize(size);

autoptrArray.SetSize(size);

for(int i=0;i<size;i++)

{

automarkArray[i]=(theCPtr->m_AutoMark)[i];

autoptrArray[i]=(theCPtr->AutoPtrArray)[i];

}

m_mark=theCPtr->m_mark;

}

BOOL CMark::bIsNoneInStack()

{

int size=automarkArray.GetSize();

if(size==0)

return FALSE;

for(int i=0;i<size;i++)

{

if(automarkArray[i]<=0)

return FALSE;

}

return TRUE;

}

void CMark::Release()

{

int size=autoptrArray.GetSize();

for(int i=0;i<size;i++)

{

parent_autoptr * thePtr=

(parent_autoptr *)autoptrArray[i];

thePtr->Release();

}

}

file://end Calss CMark

file://begin class CMarkTable

void CMarkTable::AddCMark(CMark * theCMark)

{

if(theCMark)

CMarkArray.Add(theCMark);

}

BOOL CMarkTable::FindMark(int mark)

{

int size=CMarkArray.GetSize();

for(int i=0;i<size;i++)

{

CMark * theMark=(CMark *)CMarkArray[i];

if(theMark)

{

if(mark==theMark->m_mark)

return TRUE;

}

}

return FALSE;

}

void CMarkTable::GetLockMark()

{

CLockMarkArray.SetSize(0);

int size=CMarkArray.GetSize();

for(int i=0;i<size;i++)

{

CMark * theMark=(CMark*)CMarkArray[i];

if(theMark)

{

if(theMark->bIsNoneInStack())

CLockMarkArray.SetAtGrow(i,theMark);

}

}

}

void CMarkTable::RemoveUnlockMark()

{

CUIntArray UnlockMarkArray;

BOOL bNoneRemoveed;

do

{

bNoneRemoveed=TRUE;

UnlockMarkArray.SetSize(0);

int size=CLockMarkArray.GetSize();

for(int i=0;i<size;i++)

{

CMark * theMark=(CMark*)CLockMarkArray[i];

if(theMark)

{

int size1=(theMark->automarkArray).GetSize();

for(int j=0;j<size1;j++)

{

int mark=(theMark->automarkArray)[j];

if(!FindLockMark(mark))

{

UnlockMarkArray.InsertAt(0,i); file://record to remove

bNoneRemoveed=FALSE;

break;

}

}

}

else

{

UnlockMarkArray.InsertAt(0,i);

bNoneRemoveed=FALSE;

}

}

int size2=UnlockMarkArray.GetSize();

for(int k=0;k<size2;k++)

{

int m=UnlockMarkArray[k];

CLockMarkArray.RemoveAt(m);

}

}while(!bNoneRemoveed);

}

BOOL CMarkTable::FindLockMark(int mark)

{

int size=CLockMarkArray.GetSize();

for(int i=0;i<size;i++)

{

CMark * theMark=(CMark *)CLockMarkArray[i];

if(theMark)

{

if(mark==theMark->m_mark)

return TRUE;

}

}

return FALSE;

}

void CMarkTable::RemoveGroup(int automark)

{

int size=CLockMarkArray.GetSize();

for(int i=0;i<size;i++)

{

CMark * theMark=(CMark *)CLockMarkArray[i];

if(theMark)

{

if(automark==theMark->m_mark)

{

CLockMarkArray.RemoveAt(i);

int size2=

(theMark->automarkArray).GetSize();

for(int j=0;j<size2;j++)

{

int auto_mark=

(theMark->automarkArray)[j];

RemoveGroup(auto_mark);

}

break;

}

}

}

}

void CMarkTable::DoLockMark()

{

GetLockMark();

RemoveUnlockMark();

int size=CLockMarkArray.GetSize();

while(size)

{

CMark* theMark=(CMark*)CLockMarkArray[0];

CLockMarkArray.RemoveAt(0);

if(theMark)

{

int size2=

(theMark->automarkArray).GetSize();

for(int i=0;i<size2;i++)

{

int automark=

(theMark->automarkArray)[i];

RemoveGroup(automark);

}

theMark->Release();

}

size=CLockMarkArray.GetSize();

}

Init();

}

void CMarkTable::Init()

{

int size=CMarkArray.GetSize();

for(int i=0;i<size;i++)

{

CMark* theMark=(CMark*)CMarkArray[i];

if(theMark)

delete theMark;

}

CMarkArray.SetSize(0);

CLockMarkArray.SetSize(0);

}

file://end class CMarkTable

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有