GIDForums  

Go Back   GIDForums > Computer Programming Forums > CPP / C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 02-Nov-2005, 07:23
gaoanyu gaoanyu is offline
New Member
 
Join Date: Jun 2005
Location: Bristol, UK
Posts: 26
gaoanyu is on a distinguished road

Strange C++ code memory leakage problem


Dear Friends,

I have a very strange (to me) memory leakage problem in my C++ source code.

I have included

CPP / C++ / C Code:
#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)

in the precompiled header file, and also included

CPP / C++ / C Code:
#define new DEBUG_NEW


in every .cpp files.

In my main function, I added in the end

CPP / C++ / C Code:
_CrtDumpMemoryLeaks()

I did the above in order to let the debugger tells me where the memory leakage occurs.

On top of that, I also intentionally included the following line before _CrtDumpMemoryLeaks() without de-allocating the memory, to make sure my added codes really shows me where the memory leakage occurs.

CPP / C++ / C Code:
	int *array = new int[3];
	for (int i=0;i<3;i++)
	{
		array[i] = i;
	}

After all these, I get the following from the output window (.NET):

Code:
'MCWEnD.exe': Loaded 'D:\NET\main_ori\main\bin\MCWEnD.exe', Symbols loaded. 'MCWEnD.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded. 'MCWEnD.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded. Detected memory leaks! Dumping objects -> d:\net\main_ori\main\mcwen\mcwencoder.cpp(661) : {85702} normal block at 0x036F4F48, 12 bytes long. Data: < > 00 00 00 00 01 00 00 00 02 00 00 00 {75807} normal block at 0x033A7EC0, 0 bytes long. Data: <> {75806} normal block at 0x033A7E80, 0 bytes long. Data: <> {75805} normal block at 0x033A7E40, 0 bytes long. Data: <> {75804} normal block at 0x033A7E00, 0 bytes long. Data: <> {75803} normal block at 0x033A7DC0, 0 bytes long. Data: <> {75802} normal block at 0x033A7D80, 0 bytes long. Data: <> {75801} normal block at 0x033A7D40, 0 bytes long. Data: <> {75800} normal block at 0x033A7D00, 0 bytes long. Data: <> {75783} normal block at 0x033A7798, 0 bytes long. Data: <> {75782} normal block at 0x033A7758, 0 bytes long. Data: <> {75781} normal block at 0x033A7718, 0 bytes long. Data: <> {75780} normal block at 0x033A76D8, 0 bytes long. Data: <> {75779} normal block at 0x033A7698, 0 bytes long. Data: <> {75778} normal block at 0x033A7658, 0 bytes long. Data: <> {75777} normal block at 0x033A71A0, 0 bytes long. Data: <> {75776} normal block at 0x033A62D0, 0 bytes long. Data: <> {75756} normal block at 0x033A6EE0, 0 bytes long. Data: <> {75755} normal block at 0x033A6EA0, 0 bytes long. Data: <> {75754} normal block at 0x033A6E60, 0 bytes long. Data: <> {75753} normal block at 0x033A6E20, 0 bytes long. Data: <> {75752} normal block at 0x033A6DE0, 0 bytes long. Data: <> {75751} normal block at 0x033A6DA0, 0 bytes long. Data: <> {75750} normal block at 0x033A6D60, 0 bytes long. Data: <> {75749} normal block at 0x033A6D20, 0 bytes long. Data: <> {75731} normal block at 0x033A6778, 0 bytes long. Data: <> {75730} normal block at 0x033A6738, 0 bytes long. Data: <> {75729} normal block at 0x033A66F8, 0 bytes long. Data: <> {75728} normal block at 0x033A66B8, 0 bytes long. Data: <> {75727} normal block at 0x033A6678, 0 bytes long. Data: <> {75726} normal block at 0x033A6638, 0 bytes long. Data: <> {75725} normal block at 0x033A65F8, 0 bytes long. Data: <> {75724} normal block at 0x033A65B8, 0 bytes long. Data: <> Object dump complete.

I included the full output for the sake of completeness. My question is, as you can see, the intentionally allocated memory (int* array) is picked up by the debugger (the first line in the output), it shows me the file allocation and linenumber so that I can track back. However, the other memory leakages seem every strange. 1) it does not show me where the leakage occurs; 2) it shows a memory location but with 0 bytes long..

Do any of you have any suugestion as what may be the cause of these?? Your comments are highly appreciated. Thank you very much.

David
Last edited by LuciWiz : 02-Nov-2005 at 09:10. Reason: Please insert your C++ code between [c++] & [/c++] tags
  #2  
Old 02-Nov-2005, 09:06
Paramesh's Avatar
Paramesh Paramesh is offline
Regular Member
 
Join Date: Sep 2005
Location: The Milky Way
Posts: 922
Paramesh is a jewel in the roughParamesh is a jewel in the roughParamesh is a jewel in the rough

Re: Strange C++ code memory leakage problem


Hi David,

I dont know in depth about this but:

I think you should delete the allocated array using the delete statement so that some of the memory leaks will be gone.

You can find more information about those in this link:
Memory Leaks

Regarding the 0 byte memory leaks, I found some information and here it is:

The C Runtime will allocate memory for the entry and in debug- version also for the "overwrite" marker at beginning and end of the allocation.
The C runtime heap has to set aside workspace to hold that pointer, etc. Try allocating 1,000,000 0 byte blocks and see what happens - memory is definitely being consumed.

Regards,
Paramesh.
__________________

Don't walk in front of me, I may not follow.
Don't walk behind me, I may not lead.
Just walk beside me and be my friend.
  #3  
Old 02-Nov-2005, 10:04
gaoanyu gaoanyu is offline
New Member
 
Join Date: Jun 2005
Location: Bristol, UK
Posts: 26
gaoanyu is on a distinguished road

Re: Strange C++ code memory leakage problem


Dear Paramesh,

Many thanks for your comments . Actually that array was intentionally undeleted to show the difference in the output window.

I think it maybe useful to include the _CrtMemDumpStatistics() output as well, the two states shown here are snapshots taken at the very beginning and the very end in my main() function. Here goes:


0 bytes in 0 Free Blocks.
0 bytes in 0 Normal Blocks.
6293 bytes in 43 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 7785 bytes.
Total allocations: 9961 bytes.

0 bytes in 0 Free Blocks.
0 bytes in 32 Normal Blocks.
23605 bytes in 69 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 66100082 bytes.
Total allocations: 75856046 bytes.


As can be seen, the second state has "0 bytes in 32 Normal Blocks.", and this is where I am so confused.. Thank you for any comment.

David
  #4  
Old 02-Nov-2005, 10:43
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,623
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Strange C++ code memory leakage problem


Quote:
Originally Posted by gaoanyu
Dear Friends,

I have a very strange (to me) memory leakage problem in my C++ source code.

Code:
{75724} normal block at 0x033A65B8, 0 bytes long. Data: <> Object dump complete.

This points to line number 75724. Is your file really that long? (Or have you included something else in your file that causes it to be that long?)

It is indicating a block length of zero bytes. How can this happen?

I have seen this in buggy code that had something like char *y = new char[0];. That is allocating an block of memory that has zero bytes in it (!) I don't think there is anything illegal about allocating a zero-length array, but you can't legally store anything there. But the point is, compilers cheerfully accept such code --- sometimes leading to (inconsistently) bad stuff at run time.

Actually, the code looked something like this:

CPP / C++ / C Code:
  int n;
  char *y;
..
..

  y = new char[n];
..

If n == 0 when the new operator is used like this, it creates an array of length zero.

Along those same lines, maybe there is a class constructor with something like

CPP / C++ / C Code:
m_class::m_class(n)
{
..
..
  y = new char[n];
}

Where the member y is a pointer to char. Now, if an object is instantiated with n == 0:
CPP / C++ / C Code:
m_class my_mclass(n);

Maybe there are other ways of allocating memory blocks with length 0??? Check your code.


Regards,

Dave
  #5  
Old 03-Nov-2005, 04:55
gaoanyu gaoanyu is offline
New Member
 
Join Date: Jun 2005
Location: Bristol, UK
Posts: 26
gaoanyu is on a distinguished road

Re: Strange C++ code memory leakage problem


Dear Dave,

Thanks a lot for your comments (as always). I tried your buggy code to allocate an array of 0 byte, and it showed me in the output window:

Detected memory leaks!
Dumping objects ->
d:\c\test\mem_leak.cpp(51) : {45} normal block at 0x00322FB8, 0 bytes long.
Data: <>
Object dump complete.


As you can see, the length is really 0 bytes long, however, I have been able to see where the problem lies, i.e. "d:\c\test\mem_leak.cpp(51)". However, as in my previous case, I had no idea where the problem came from.

Last night, I managed to find where the problem is, by setting breakpoints on the memory numbers, for example, {75724}. And I can see that every time that function is called, a 0 byte long leakage occurs. But I still have no idea as why this is happening. Apparently, it has something to do with resizing the vector. Below is the buggy line in my source code:

Code:
m_MotionInfoParam_SB.Resize(m_nNum_SBand_Pres);

m_MotionInfoParam_SB is a vector of structures, and m_nNum_SBand_Pres is simply an int.

Any comments? Many thanks!
  #6  
Old 03-Nov-2005, 06:29
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,623
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Strange C++ code memory leakage problem


Quote:
Originally Posted by gaoanyu
Dear Dave,


Apparently, it has something to do with resizing the vector. Below is the buggy line in my source code:

Code:
m_MotionInfoParam_SB.Resize(m_nNum_SBand_Pres);

m_MotionInfoParam_SB is a vector of structures, and m_nNum_SBand_Pres is simply an int.

This line is not buggy. I would guess that the function that it is calling is buggy.

So: What does the Resize() member function look like in the class definition? Can you post the code for this function?

Just a wild guess: sometimes functions with names like resize do some memory allocation. What do you think would happen if a resize function is called with 0 as an argument? (Looks like an ideal opportunity for a buggy function to create a memory leak, but how can anyone tell unless they see the code for the function?)

Regards,

Dave
  #7  
Old 04-Nov-2005, 03:26
gaoanyu gaoanyu is offline
New Member
 
Join Date: Jun 2005
Location: Bristol, UK
Posts: 26
gaoanyu is on a distinguished road

Re: Strange C++ code memory leakage problem


Dear Dave,

Many thanks for your comments. I was afraid that the codes were too long, so I did not include those. But here they go: I have included all the functions, because they maybe helpful in reading the codes.

CPP / C++ / C Code:
template<class ValueType>
class CVectorBase {
public:
    typedef CVectorBase<ValueType> MyVectorBase;
    typedef ValueType*             ValueTypePtr;
    typedef const ValueType*       ValueTypeConstPtr;
    typedef ValueType&             ValueTypeRef;
    typedef const ValueType&       ValueTypeConstRef;
    CVectorBase(): m_pFirstVal(0), m_pLastVal(0), m_pEndVal(0) {}
	CVectorBase(size_t uSize, const ValueType& Val = ValueType())
	{
        m_pFirstVal = _ALLOCATE(uSize,(ValueTypePtr)NULL);
		FillVectorWith(m_pFirstVal, uSize, Val);
		m_pLastVal = m_pFirstVal + uSize;
		m_pEndVal = m_pLastVal; 
    }
	CVectorBase(const MyVectorBase& _X)
	{
        m_pFirstVal = _ALLOCATE(_X.GetSize(),(ValueTypePtr)NULL);
		m_pLastVal = CopyVector(_X.GetBeginPtr(), _X.GetEndPtr(), m_pFirstVal);
		m_pEndVal = m_pLastVal; 
    }
	CVectorBase(ValueTypeConstPtr pBeginPtr, 
                ValueTypeConstPtr pEndPtr)
	:m_pFirstVal(0), m_pLastVal(0), m_pEndVal(0)
	{
        Insert(GetBeginPtr(), pBeginPtr, pEndPtr); 
    }
	~CVectorBase()
	{
        Destroy(m_pFirstVal, m_pLastVal);
        _DEALLOCATE((void*)m_pFirstVal);
		m_pFirstVal = 0, m_pLastVal = 0, m_pEndVal = 0; 
    }
	MyVectorBase& operator=(const MyVectorBase& _X)
	{
        if (this == &_X)
			;
		else if (_X.GetSize() <= GetSize())
		{
            ValueTypePtr _S = _COPY(_X.GetBeginPtr(), _X.GetEndPtr(), m_pFirstVal);
			Destroy(_S, m_pLastVal);
			m_pLastVal = m_pFirstVal + _X.GetSize(); 
        }
		else if (_X.GetSize() <= GetMaxSize())
		{
            ValueTypeConstPtr _S = _X.GetBeginPtr() + GetSize();
			_COPY(_X.GetBeginPtr(), _S, m_pFirstVal);
			CopyVector(_S, _X.GetEndPtr(), m_pLastVal);
			m_pLastVal = m_pFirstVal + _X.GetSize(); 
        }
		else
		{
            Destroy(m_pFirstVal, m_pLastVal);
            
			_DEALLOCATE(m_pFirstVal);
			m_pFirstVal = _ALLOCATE(_X.GetSize(),(ValueTypePtr)NULL);
			m_pLastVal = CopyVector(_X.GetBeginPtr(), _X.GetEndPtr(),
				m_pFirstVal);
			m_pEndVal = m_pLastVal; 
        }
		return (*this); 
    }
	void Reserve(size_t uSize)
	{
        if (GetMaxSize() < uSize)
		{
            ValueTypePtr pAllocPtr = _ALLOCATE(uSize,(ValueTypePtr)NULL);
			CopyVector(m_pFirstVal, m_pLastVal, pAllocPtr);
			Destroy(m_pFirstVal, m_pLastVal);
            _DEALLOCATE(m_pFirstVal);
			m_pEndVal = pAllocPtr + uSize;
			m_pLastVal = pAllocPtr + GetSize();
			m_pFirstVal = pAllocPtr; 
        }
    }
	void Resize(size_t uNewSize, const ValueType& InitVal = ValueType())
	{
        if (GetSize() < uNewSize)
			Insert(GetEndPtr(), uNewSize - GetSize(), InitVal);
		else if (uNewSize < GetSize())
			Remove(GetBeginPtr() + uNewSize, GetEndPtr()); 
    }
	size_t GetSize() const
	{
        return (m_pFirstVal == 0 ? 0 : m_pLastVal - m_pFirstVal); 
    }
	bool IsEmpty() const
	{
        return (GetSize() == 0); 
    }
	ValueTypeConstRef GetAt(size_t _P) const
	{
        if (GetSize() <= _P)
        {
            // out of range;
            assert(0);
        }
		return (*(GetBeginPtr() + _P)); 
    }
	ValueTypeRef GetAt(size_t uIdx)
	{
        assert(GetSize() > uIdx);
		return (*(GetBeginPtr() + uIdx)); 
    }
	ValueTypeConstRef operator[](size_t uIdx) const
	{
        return (*(GetBeginPtr() + uIdx)); 
    }
	ValueTypeRef operator[](size_t uIdx)
	{
        return (*(GetBeginPtr() + uIdx)); 
    }
	void PushBack(const ValueType& _X)
	{
        Insert(GetEndPtr(), _X); 
    }
	void PopBack()
	{
        Remove(GetEndPtr() - 1); 
    }
	void Assign(ValueTypeConstPtr pBeginPtr, ValueTypeConstPtr pEndPtr)
	{
        Remove(GetBeginPtr(), GetEndPtr());
		Insert(GetBeginPtr(), pBeginPtr, pEndPtr); 
    }
	void Assign(size_t uSize, const ValueType& Val = ValueType())
	{
        Remove(GetBeginPtr(), GetEndPtr());
		Insert(GetBeginPtr(), uSize, Val); 
    }
	ValueTypePtr Insert(ValueTypePtr pPrevPtr, const ValueType& Val = ValueType())
	{
        size_t uOffset = pPrevPtr - GetBeginPtr();
		Insert(pPrevPtr, 1, Val);
		return (GetBeginPtr() + uOffset); 
    }
	void Insert(ValueTypePtr pPrevPtr, size_t uSize, const ValueType& Val)
	{
        if (m_pEndVal - m_pLastVal < (int)uSize)
		{
            size_t uAllocSize = GetSize() + (uSize < GetSize() ? GetSize() : uSize);
			ValueTypePtr pAllocStartPtr = _ALLOCATE(uAllocSize, (ValueTypePtr)NULL);
			ValueTypePtr pAllocEndPtr = CopyVector(m_pFirstVal, pPrevPtr, pAllocStartPtr);
			FillVectorWith(pAllocEndPtr, uSize, Val);
			CopyVector(pPrevPtr, m_pLastVal, pAllocEndPtr + uSize);

			Destroy(m_pFirstVal, m_pLastVal);
			_DEALLOCATE(m_pFirstVal);

			m_pEndVal = pAllocStartPtr + uAllocSize;
			m_pLastVal = pAllocStartPtr + GetSize() + uSize;
			m_pFirstVal = pAllocStartPtr; 
        }
		else if (m_pLastVal - pPrevPtr < (int)uSize)
		{
            CopyVector(pPrevPtr, m_pLastVal, pPrevPtr + uSize);
			FillVectorWith(m_pLastVal, uSize - (m_pLastVal - pPrevPtr), Val);
			_FILL(pPrevPtr, m_pLastVal, Val);
			m_pLastVal += uSize; 
        }
		else if (0 < uSize)
		{
            CopyVector(m_pLastVal - uSize, m_pLastVal, m_pLastVal);
			CopyBackward(pPrevPtr, m_pLastVal - uSize, m_pLastVal);
			_FILL(pPrevPtr, pPrevPtr + uSize, Val);
			m_pLastVal += uSize; 
        }
    }
	void Insert(ValueTypePtr pValPtr, ValueTypeConstPtr pStartPtr, ValueTypeConstPtr pEndPtr)
	{
        size_t uDiff = 0;
		uDiff = pEndPtr - pStartPtr;
		if (m_pEndVal - m_pLastVal < uDiff)
		{
            size_t uAllocSize = GetSize() + (uDiff < GetSize() ? GetSize() : uDiff);
			ValueTypePtr pAllocStartPtr = allocator.allocate(uAllocSize, (void *)0);
			ValueTypePtr pAllocEndPtr = CopyVector(m_pFirstVal, pValPtr, pAllocStartPtr);
			pAllocEndPtr = CopyVector(pStartPtr, pEndPtr, pAllocEndPtr);
			CopyVector(pValPtr, m_pLastVal, pAllocEndPtr);

			Destroy(m_pFirstVal, m_pLastVal);
            _DEALLOCATE(m_pFirstVal);

			m_pEndVal = pAllocStartPtr + uAllocSize;
			m_pLastVal = pAllocStartPtr + GetSize() + uDiff;
			m_pFirstVal = pAllocStartPtr; 
        }
		else if (m_pLastVal - pValPtr < uDiff)
		{
            CopyVector(pValPtr, m_pLastVal, pValPtr + uDiff);
			CopyVector(pStartPtr + (m_pLastVal - pValPtr), pEndPtr, m_pLastVal);
			_COPY(pStartPtr, pStartPtr + (m_pLastVal - pValPtr), pValPtr);
			m_pLastVal += uDiff; 
        }
		else if (0 < uDiff)
		{
            CopyVector(m_pLastVal - uDiff, m_pLastVal, m_pLastVal);
			CopyBackward(pValPtr, m_pLastVal - uDiff, m_pLastVal);
			_COPY(pStartPtr, pEndPtr, pValPtr);
			m_pLastVal += uDiff; 
        }
    }
	ValueTypePtr Remove(ValueTypePtr pValPtr)
	{
        _COPY(pValPtr + 1, GetEndPtr(), pValPtr);
		Destroy(m_pLastVal - 1, m_pLastVal);
		--m_pLastVal;
		return (pValPtr); 
    }
	ValueTypePtr Remove(ValueTypePtr pStartPtr, ValueTypePtr pEndPtr)
	{
        ValueTypePtr _S = _COPY(pEndPtr, GetEndPtr(), pStartPtr);
		Destroy(_S, GetEndPtr());
		m_pLastVal = _S;
		return (pStartPtr); 
    }
	void RemoveAll()
	{
        Remove(GetBeginPtr(), GetEndPtr()); 
    }
	void Swap(MyVectorBase& _X)
	{
        if (allocator == _X.allocator)
		{
            _SWAP(m_pFirstVal, _X.m_pFirstVal);
			_SWAP(m_pLastVal, _X.m_pLastVal);
			_SWAP(m_pEndVal, _X.m_pEndVal); 
        }
		else
		{
            MyVectorBase _Ts = *this; *this = _X, _X = _Ts; 
        }
    }
	friend void Swap(MyVectorBase& _X, MyVectorBase& _Y)
	{
        _X.Swap(_Y); 
    }
protected:
    size_t GetMaxSize() const
    {
        return (m_pFirstVal == 0 ? 0 : m_pEndVal - m_pFirstVal); 
    }
    ValueTypePtr GetBeginPtr()
    {
        return (m_pFirstVal); 
    }
    ValueTypeConstPtr GetBeginPtr() const
    {
        return ((ValueTypeConstPtr)m_pFirstVal); 
    }
    ValueTypePtr GetEndPtr()
    {
        return (m_pLastVal); 
    }
    ValueTypeConstPtr GetEndPtr() const
    {
        return ((ValueTypeConstPtr)m_pLastVal); 
    }
    
	void Destroy(ValueTypePtr _F, ValueTypePtr _L)
	{
        for (; _F != _L; ++_F)
            _DESTRUCT(_F);
    }
	ValueTypePtr CopyVector(ValueTypeConstPtr SrcStart, ValueTypeConstPtr SrcEnd,ValueTypePtr DstStart)
	{
        for (; SrcStart != SrcEnd; ++DstStart, ++SrcStart)
            _CONSTRUCT(DstStart, *SrcStart);
		return (DstStart); 
    }
	void FillVectorWith(ValueTypePtr DstStartPtr, size_t uSize, const ValueType &_X)
	{
        for (; 0 < uSize; --uSize, ++DstStartPtr)
        {
            _CONSTRUCT(DstStartPtr, _X);
        }
    }
	ValueTypePtr m_pFirstVal, m_pLastVal, m_pEndVal;
};

In my previous post, m_MotionInfoParam_SB is actually defined like this:

CPP / C++ / C Code:
	CVectorBase<MOTION_INFO> m_MotionInfoParam_SB;

Where MOTION_INFO is a structure, defined as follows:

CPP / C++ / C Code:
typedef struct _MOTION_INFO
{
    CVideoFrameFloatBuf*  pCenterImg;  
    CVideoFrameFloatBuf*  pLeftRef; 
    CVideoFrameFloatBuf*  pRightRef;

    int_32s               nViewLayer;
    int_32s               nStartLayer;
    int_32s               nEndLayer;
    CVectorBase<int>      iSearchRange;
    CVectorBase<float>    flLambdaMotion;

    int_32s               nTLevel;
}MOTION_INFO;

Types CVideoFrameFloatBuf* do inlcude a lot of memory allocations:

CPP / C++ / C Code:
typedef CVFrmBufBase<float> CVideoFrameFloatBuf;

CPP / C++ / C Code:
template<class ValueType>
class CVFrmBufBase
{
public:
             CBufBase2D<float>    m_pfOrgImgY;
	CBufBase2D<float>    m_pfOrgImgU;
	CBufBase2D<float>    m_pfOrgImgV;
             //A lot of CBufBase2D<float>, omit here.....

Classs CBufBase2D is simply a 2D buffer, as follows.

CPP / C++ / C Code:
template<class ValueType> 
class CBufBase2D
{
public:
    CBufBase2D(int nWidth =0,int nHeight =0,int nFrameEdge = 0)
    {
        Init();
        if(nWidth * nHeight > 0)
        {
            ReallocBuf(nWidth,nHeight,nFrameEdge);
        }
    }
    CBufBase2D(const CBufBase2D<ValueType>& SrcBase)
    {
        Init();
        if(SrcBase.m_nWidth * SrcBase.m_nHeight > 0)
        {
            ReallocBuf(SrcBase.m_nWidth,SrcBase.m_nHeight,SrcBase.m_nFrameEdge);
            MemCopy(this->m_pBufBaseAlloc,SrcBase.m_pBufBaseAlloc,sizeof(ValueType) * SrcBase.m_nAllocSize);
        }
    }
    CBufBase2D<ValueType>& operator = (const CBufBase2D<ValueType>& SrcBase)
    {
        Release();
        Init();
        if(SrcBase.m_nWidth * SrcBase.m_nHeight > 0)
        {
            ReallocBuf(SrcBase.m_nWidth,SrcBase.m_nHeight,SrcBase.m_nFrameEdge);
            MemCopy(this->m_pBufBaseAlloc,SrcBase.m_pBufBaseAlloc,sizeof(ValueType) * SrcBase.m_nAllocSize);
        }
        return *this;
    }
    void Init()
    {
        m_pBufStart = NULL;
        m_pBufBaseAlloc = NULL;
        m_ppBufIdxArray = NULL;
        
        m_nWidth     = 0;
        m_nHeight    = 0;
        m_nStep      = 0;
        m_nFrameEdge = 0;
        m_nAllocSize = 0;
    }
    void Release()
    {
        SAFEFREE(m_pBufBaseAlloc);
        SAFEFREE(m_ppBufIdxArray);
    }
    ~CBufBase2D()
    {
        Release();
    }
    operator ValueType** () 
    {
        return m_pBufStart;
    }
    ValueType& GetAt(int y,int x)
    {
        assert(x >=0 && x < m_nWidth);
        assert(y >=0 && y < m_nHeight);
        return (*this)[y][x];
    }
    void ScaleFactor(ValueType fVal)
    {
        for(int j=0;j<m_nHeight;j++)
            for(int i=0;i<m_nWidth;i++)
            {
                (*this)[j][i] *= fVal;
            }
    }
    
    int GetWidth() const 
    {
        return m_nWidth;
    }
    int GetHeight() const 
    {
        return m_nHeight;
    }
    int GetFrameEdge() const 
    {
        return m_nFrameEdge;
    }
    int GetAllocSize() const 
    {
        return m_nAllocSize;
    }
    ValueType*  GetAllocData() const 
    {
        return m_pBufBaseAlloc;
    }
    void Clear()
    {
        if(m_nWidth * m_nHeight > 0)
        {
            assert(m_nAllocSize >0);
            MemClear(m_pBufBaseAlloc,m_nAllocSize *sizeof(ValueType));
        }
    }
    void Fill(ValueType Val)
    {
        for(int i=0;i<GetAllocSize();i++)
        {
            m_pBufBaseAlloc[i] = Val;
        }
    }
    
    ERR_RES ReallocBuf(int nWidth,int nHeight,int nFrameEdge)
    {
        assert(nWidth >0 && nHeight >0);
        if(nWidth != m_nWidth || nHeight != m_nHeight || m_nFrameEdge != nFrameEdge)
        {
            Release();
            int i;
            m_nAllocSize  = (nWidth + 2 * nFrameEdge)*(nHeight + 2 * nFrameEdge);
            m_pBufBaseAlloc   = (ValueType*)MemAlloc(m_nAllocSize *sizeof(ValueType));
            if(!m_pBufBaseAlloc)
                return ERR_MEMALLOCFAILED;
            
            m_ppBufIdxArray = (ValueType**)MemAlloc((nHeight + 2 * nFrameEdge) *sizeof(ValueType*));
            if(!m_ppBufIdxArray)
                return ERR_MEMALLOCFAILED;
            
            m_nWidth  = nWidth;
            m_nHeight = nHeight;
            m_nFrameEdge = nFrameEdge;
            m_nStep = nWidth + 2 *  m_nFrameEdge;
            
            ValueType* pBufStart = m_pBufBaseAlloc + nFrameEdge;
            for(i=0;i<nHeight + 2 * nFrameEdge;i++)
            {
                m_ppBufIdxArray[i] = pBufStart;
                pBufStart += m_nStep;
            }
            m_pBufStart = &(m_ppBufIdxArray[nFrameEdge]);
        }

        return NOERR;
    }
    int GetStep()
    {
        return m_nStep;
    }
    bool operator==(const CBufBase2D<ValueType>& SrcBuf) const
    {
        bool bRet = (this->m_nWidth == SrcBuf.m_nWidth) && 
                    (this->m_nHeight == SrcBuf.m_nHeight) && 
                    (this->m_nFrameEdge == SrcBuf.m_nFrameEdge);
        if(bRet)
        {
            bRet = (0 == memcmp(this->m_pBufBaseAlloc,SrcBuf.m_pBufBaseAlloc,this->m_nAllocSize * sizeof(ValueType)));
        }
        return (bRet); 
    }
protected:
    ValueType*   m_pBufBaseAlloc;
    ValueType**  m_ppBufIdxArray;
    ValueType**  m_pBufStart;
    int          m_nAllocSize;
    int m_nWidth;
    int m_nHeight;
    int m_nFrameEdge;
    int m_nStep;
};

Sorry for such a long post, I have tried to included the information that I think might be useful. Thank you very much for taking your time. Thanks a million!

David
Last edited by LuciWiz : 04-Nov-2005 at 06:48. Reason: Please insert your C++ code between [c++] & [/c++] tags
  #8  
Old 04-Nov-2005, 08:09
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,623
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Strange C++ code memory leakage problem


Quote:
Originally Posted by gaoanyu
Dear Dave,

Many thanks for your comments. I was afraid that the codes were too long, so I did not include those. But here they go:
.
.
Sorry for such a long post, I have tried to included the information that I think might be useful

It is useful to let me see what you are dealing with, although obviously I don't have enough information to debug the entire thing (And I probably wouldn't, anyhow.)

In the first place, I don't think that being left with pointers that point to blocks of size zero necessarily represents a memory leak. (If the blocks themselves have been de-allocated, then that's OK.) They do present the possibility of corrupting memory if some other probram bug results in reusing that pointer for something after the memory is no longer valid. Ordinarily, we would set pointers to zero when the memory is deallocated. More importantly, since you are diligently searching for memory leaks, they confuse the statistics.


Now: Since from your previous post, the debug routine showed problems associated with the Resize function, I would concentrate there. I have no way of knowing how your program actually uses these functions, but I would have to ask what would be the effect of calling Resize with an argument value of uNewsize = 0.

I think it leaves a pointer that is pointing to memory that has been deallocated by the destroy() routine. The destroy() routine actually de-allocates the objects that the pointer was pointing to.

But maybe (one might actually say "probably") I am wrong. It's up to you to see what the heck it's doing.

Here's how I might approach the situation:

Make a small program that puts a couple of objects in a list and see if the memory leak statistics show the puzzling output.

Try resizing a few times, including resize zero. See what happens. Try to get the smallest possible main() program that exhibits the puzzling behavior.

Put cout<< in the Resize function to see what values are being used. Trace the action by putting cout<< in destroy(), etc.


Regards,

Dave

"We can face our problem.
We can arrange such facts as we have
with order and method."

Hercule Poirot
--- in Murder on the Orient Express
 
 

Recent GIDBlogToyota - 2008 July Promotion by Nihal

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with porting of Linux code to Windows, FORTRAN/C. stormlab Computer Software Forum - Linux 0 14-Oct-2005 12:25
Pointer Usage in C++: Beginner to Advanced varunhome CPP / C++ Forum 0 19-Aug-2005 09:25
Guidelines for posting requests for help - UPDATED! WaltP CPP / C++ Forum 0 21-Apr-2005 02:44
[Tutorial] Pointers in C (Part I) Stack Overflow C Programming Language 1 08-Apr-2005 18:35

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 18:27.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.