靈巧指標與垃圾回收原始碼 (轉)
本人將貼上於此,各位有興趣的網友可以測試一試。
說明:
只要將兩個加入到你的工程中,並在你的CWinApp派生類中加入如下一句即可:
CPtrManager thePtrManager;
然後,在使用普通指標的地方,用靈巧指標替換即可,假如有一個類test,並有如下應用:
test * ptest=new test;
other code
delete ptest;
現在可這樣應用:
auto_ptr
other code
再不用人為的delete ptest 了,垃圾回收將自動清除,即使你有如下應用:
auto_ptr
test mytest;
ptest=&mytest;
你也不用擔心,靈巧指標也不會誤刪你在棧中的。
只要大家認真幫我測試這段程式碼到沒有 ,並對部分演算法進行和改進,那麼,我可以相信:“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(CSync* 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; 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 auto_ptr :public parent_autoptr
{
public:
virtual void Release(){Remove();}
auto_ptr()
{mark=0;pointee=0;thisAutoMark=GetAutoMark();}
auto_ptr(auto_ptr
auto_ptr(T*ptr);
~auto_ptr(){Remove();}
T*operator->() const;
operator T*();
T&operator*()const;
auto_ptr
auto_ptr
private:
void Remove();
int GetAutoMark();
CMutex *GetCMutex();
void ReadyWrite();
T*pointee;
int mark;
};
template
{
return pointee;
}
template
{
CPtrManager * pMana=CPtrManager::GetPtrManager();
if(pMana)
{
for(;;)
{
if(pMana->bCanWrite())
break;
}
}
}
template
{
CPtrManager * pMana=CPtrManager::GetPtrManager();
if(pMana)
{
return pMana->GetAutoMark(this);
}
return 0;
}
template
{
CPtrManager * pMana=CPtrManager::GetPtrManager();
if(pMana)
{
CPtr * theCPtr=pMana->GetCPtr(pointee,mark);
if(theCPtr)
return theCPtr->GetCMutex();
}
return NULL;
}
template
{
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
{
dec to do
}
}
pointee=NULL;
mark=0;
if(!bDeleteLock)
delete pLock;
}
}
template
{
return pointee;
}
template
{
return *pointee;
}
template
{
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
{
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
{
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
{
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
};
#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
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
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() 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
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() 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
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
theIntArray.SetAtGrow(i,i+1);
}
bWrite=FALSE;
BOOL bALLCopyed=TRUE;
int TotalWhile=0;
do
{
TotalWhile++;
bALLCopyed=TRUE;
size=theIntArray.GetSize();
for(i=0;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;
}
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
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
if(automarkArray[i]<=0)
return FALSE;
}
return TRUE;
}
void CMark::Release()
{
int size=autoptrArray.GetSize();
for(int i=0;i
parent_autoptr * thePtr=
(parent_autoptr *)autoptrArray[i];
thePtr->Release();
}
}
Calss CMark
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
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
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
CMark * theMark=(CMark*)CLockMarkArray[i];
if(theMark)
{
int size1=(theMark->automarkArray).GetSize();
for(int j=0;j
int mark=(theMark->automarkArray)[j];
if(!FindLockMark(mark))
{
UnlockMarkArray.InsertAt(0,i); to remove
bNoneRemoveed=FALSE;
break;
}
}
}
else
{
UnlockMarkArray.InsertAt(0,i);
bNoneRemoveed=FALSE;
}
}
int size2=UnlockMarkArray.GetSize();
for(int k=0;k
int m=UnlockMarkArray[k];
CLockMarkArray.RemoveAt(m);
}
}while(!bNoneRemoveed);
}
BOOL CMarkTable::FindLockMark(int mark)
{
int size=CLockMarkArray.GetSize();
for(int i=0;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
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
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
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
CMark* theMark=(CMark*)CMarkArray[i];
if(theMark)
delete theMark;
}
CMarkArray.SetSize(0);
CLockMarkArray.SetSize(0);
}
class CMarkTable
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992049/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python3 原始碼閱讀 - 垃圾回收機制Python原始碼
- 垃圾回收(三)【垃圾回收通知】
- JAVA垃圾回收機制和Python垃圾回收對比與分析JavaPython
- 淺析堆與垃圾回收
- 淺談JVM與垃圾回收JVM
- 垃圾回收(一)【垃圾回收的基礎】
- JVM垃圾回收之三色標記JVM
- 垃圾回收
- JVM垃圾回收器、記憶體分配與回收策略JVM記憶體
- 通達信強烈反轉主圖指標公式原始碼指標公式原始碼
- 通達信九轉主圖指標公式原始碼主圖指標公式原始碼
- golang 垃圾回收器如何標記記憶體?Golang記憶體
- JVM 垃圾回收演算法和垃圾回收器JVM演算法
- JVM垃圾回收JVM
- 垃圾回收_上
- 垃圾回收_下
- javascript垃圾回收JavaScript
- [JVM]垃圾回收JVM
- golang垃圾回收Golang
- Python:垃圾回收Python
- 另類KDJ指標公式原始碼 2019通達信指標公式指標公式原始碼
- 垃圾回收的標記清除演算法詳解演算法
- 掌握C語言指標,輕鬆解鎖程式碼高效性與靈活性(中)C語言指標
- PHP 垃圾回收與記憶體管理指引PHP記憶體
- js--閉包與垃圾回收機制JS
- 通達信首次籌碼指標公式原始碼指標公式原始碼
- OceanBase 原始碼解讀(十二):宏塊的垃圾回收和壞塊檢查原始碼
- Unity GC垃圾回收UnityGC
- JVM垃圾回收概述JVM
- GC垃圾回收器GC
- JVM垃圾回收器JVM
- JVM垃圾回收(下)JVM
- 【Postgresql】VACUUM 垃圾回收SQL
- JVM - 垃圾回收概述JVM
- 垃圾回收演算法|GC標記-清除演算法演算法GC
- Golang 垃圾回收-三色標記清除演算法Golang演算法
- 靈茶山艾府-相向雙指標指標
- 通達信三源主圖主圖指標劃線指標原始碼指標原始碼
- 通達信漲停籌碼指標公式原始碼指標公式原始碼