Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Heap problem with template class and function 1

Status
Not open for further replies.

IonelBurtan

Programmer
May 25, 2001
601
RO
I have a template class made in C++ like this

template <class T> class
TypedArray
{
private:
T* m_pArray;
int m_nSize;
int m_nMaxSize;
const int m_nGrowBy;

public:
TypedArray():m_nGrowBy(4), m_nMaxSize(0)
{
m_nSize = 0;
m_nMaxSize = 0;
m_pArray = 0x0;
}
~TypedArray()
{
RemoveAll();
}
int GetSize(){return m_nSize;};
void RemoveAll()
{
delete[] (unsigned char*)m_pArray; // (unsigned char*)= BYTE* from windows
m_pArray = 0x0;
m_nSize = 0;
m_nMaxSize = 0;
}
long GetAt(int i)
{
return m_pArray;
}
void Add(T value)
{
if(m_nSize == m_nMaxSize) //s-a ajuns la dimensiune maxima
{
T* pTemp = new T[m_nMaxSize];
memcpy(pTemp, m_pArray, m_nMaxSize * sizeof(T));
delete[] m_pArray;
m_pArray = new T[m_nMaxSize + m_nGrowBy];
memcpy(m_pArray, pTemp, m_nMaxSize * sizeof(T));
delete[] pTemp;

m_pArray[m_nSize] = value;

m_nSize++;
m_nMaxSize+=m_nGrowBy;
}
else
{
m_nSize++;
m_pArray[m_nSize-1] = value;
}
}
int Find(T value)
{
return GetPositionInVector(m_pArray, &value, m_nSize);
}
};


In Another class CMother i have a member of type
TypedArray<int>** m_pMember alocated dinamically of size

I have problems in ~CMother() like this
{
for(int i=0; i<m_nLocalitatiDelivCount; i++)
for(int j=0; j<m_nLocalitatiDelivCount; j++)
m_arrOraseMinRoad[j].RemoveAll();
DealocaMatrice(m_arrOraseMinRoad, m_nLocalitatiDelivCount); //<--here the code cracks
}

function DealocaMatrice looks like this:

template <typename T>
void DealocaMatrice(T**& aMatrice, unsigned int nCountX)
{
if (aMatrice!=0x0 /*NULL*/)
{
for(unsigned int i=0; i<nCountX; i++)
delete aMatrice;
delete[] aMatrice; //<-here the codestops

aMatrice = 0x0;// NULL fara windows.h
}
}

TypedArray has no memory leaks and RemoveAll just leaves the heap OK. Also, function DealocaMatrice works fine in many other instances, the code is ok.
The error I get is a an ASSERT:
_BLOCK_TYPE_IS_VALID() coming from dbgdel.cpp

It just looks like I have a problem when I dealloc a heap matrix made of heap arrays. Pretty unusual situasion but I do not see why it does not works.

Tnx,
Any clue really apreciated,

s-)

Blessed is he who in the name of justice and goodwill, sheperds the weak through the valley of darkness...
 
I velieve the problem is there
delete[] (unsigned char*)m_pArray;

I can't understand, if T is for example some int, why you delete char?
let's explain,
array of int
the pointer what points the start of buffer could eb different, depending on platform
[1,2,3,4][1,2,3,4][1,2,3,4][1,2,3,4]
on platform with little endian it points there:
-------Y
[1,2,3,4][1,2,3,4][1,2,3,4][1,2,3,4]
platform with little endian points there:
-Y
[1,2,3,4][1,2,3,4][1,2,3,4][1,2,3,4]

array of char on all platform it points there:
-Y
[1,2,3,4,5,6,7,8,9,......]

Ion Filipski
1c.bmp
 
I put all the code together. It still has the same problem. You can paste it in an empty console project from VC6++.
I am also checking there for memory leaks.

Code:
// TestLongArray.cpp : Defines the entry point for the console application.
//

#include &quot;stdafx.h&quot;
#include <stdio.h>
#include <string.h>
#include <crtdbg.h>

template <typename T> 
void AlocaMatrice(T**& aMatrice, unsigned int nCountX, unsigned int nCountY)
{
	if (nCountX == 0 || nCountY == 0){aMatrice = 0x0; return;};

	aMatrice = new T*[nCountX];
	for(unsigned int i=0; i<nCountX; i++)
		aMatrice[i] = new T[nCountY];
}

template <typename T> 
void DealocaMatrice(T**& aMatrice, unsigned int nCountX)
{
	if (aMatrice!=0x0 /*NULL*/)
	{
		for(unsigned int i=0; i<nCountX; i++)
			delete (unsigned char*)aMatrice[i]; //[b]<--here the code stops[/b]
		delete[] aMatrice; 

		aMatrice = 0x0;// NULL fara windows.h
	}
}

template <class T> class
TypedArray
{
private:
	T* m_pArray;
	int m_nSize;
	int m_nMaxSize;
	const int m_nGrowBy;

public:
	TypedArray():m_nGrowBy(4), m_nMaxSize(0)
	{
		m_nSize = 0;
		m_nMaxSize = 0;
		m_pArray = 0x0;
	}
	~TypedArray()
	{
		RemoveAll();
	}
	int GetSize(){return m_nSize;};
	void RemoveAll()
	{
		delete[] m_pArray;
		m_pArray = 0x0;
		m_nSize = 0;
		m_nMaxSize = 0;
	}
	long GetAt(int i)
	{	
		return m_pArray[i];
	}
	void Add(T value)
	{
		if(m_nSize == m_nMaxSize) //s-a ajuns la dimensiune maxima
		{
			T* pTemp = new T[m_nMaxSize];
			memcpy(pTemp, m_pArray, m_nMaxSize * sizeof(T));
			delete[] m_pArray;
			m_pArray = new T[m_nMaxSize + m_nGrowBy];
			memcpy(m_pArray, pTemp, m_nMaxSize * sizeof(T));
			delete[] pTemp;

			m_pArray[m_nSize] = value;

			m_nSize++;
			m_nMaxSize+=m_nGrowBy;
		}
		else
		{
			m_nSize++;
			m_pArray[m_nSize-1] = value;
		}
	}
	int Find(T value)
	{
		return GetPositionInVector(m_pArray, &value, m_nSize);
	}
};

void Test()
{
	TypedArray<int>** m_arr;
	AlocaMatrice(m_arr, 2, 2);
	m_arr[0][0].Add(10);
	m_arr[0][0].Add(11);
	m_arr[0][1].Add(10);
	m_arr[0][1].Add(11);
	m_arr[1][0].Add(10);
	m_arr[1][0].Add(11);
	m_arr[1][1].Add(10);
	m_arr[1][1].Add(11);

	for(int i=0; i<2; i++)
		for(int j=0; j<2; j++)
			m_arr[i][j].RemoveAll();
	DealocaMatrice(m_arr, 2);

	TypedArray<int> l;
	l.Add(1);
	l.Add(2);
	l.Add(3);
	l.Add(4);
	l.Add(5);
	printf(&quot;%d\n&quot;, l.GetAt(2));
	l.Add(6);
	l.Add(7);
	l.Add(8);
	l.RemoveAll();

	TypedArray<long> g;
	g.Add(9);
	g.Add(10);
	g.Add(11);
	g.Add(12);
	g.Add(13);
	
	printf(&quot;%d, %d\n&quot;, g.GetAt(2), g.GetAt(1));
}

int main(int argc, char* argv[])
{
	int tmpDbgFlag;
	tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
	tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
	tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
	tmpDbgFlag |= _CRTDBG_ALLOC_MEM_DF;
	_CrtSetDbgFlag(tmpDbgFlag);

	Test();

	_CrtDumpMemoryLeaks( );

	return 0;
}

Tnx,

s-)

Blessed is he who in the name of justice and goodwill, sheperds the weak through the valley of darkness...
 
please put your code inside TGML tag:
[code]....[/code]
because the tag [i][/i] will be interpreted as italic

Ion Filipski
1c.bmp
 
// TestLongArray.cpp : Defines the entry point for the console application.
//

#include &quot;stdafx.h&quot;
#include <stdio.h>
#include <string.h>
#include <crtdbg.h>

template <typename T>
void AlocaMatrice(T**& aMatrice, unsigned int nCountX, unsigned int nCountY)
{
if (nCountX == 0 || nCountY == 0){aMatrice = 0x0; return;};

aMatrice = new T*[nCountX];
for(unsigned int i=0; i<nCountX; i++)
aMatrice = new T[nCountY];
}

template <typename T>
void DealocaMatrice(T**& aMatrice, unsigned int nCountX)
{
if (aMatrice!=0x0 /*NULL*/)
{
for(unsigned int i=0; i<nCountX; i++)
delete (unsigned char*)aMatrice; //<--here the code stops
delete[] aMatrice;

aMatrice = 0x0;// NULL fara windows.h
}
}

template <class T> class
TypedArray
{
private:
T* m_pArray;
int m_nSize;
int m_nMaxSize;
const int m_nGrowBy;

public:
TypedArray():m_nGrowBy(4), m_nMaxSize(0)
{
m_nSize = 0;
m_nMaxSize = 0;
m_pArray = 0x0;
}
~TypedArray()
{
RemoveAll();
}
int GetSize(){return m_nSize;};
void RemoveAll()
{
delete[] m_pArray;
m_pArray = 0x0;
m_nSize = 0;
m_nMaxSize = 0;
}
long GetAt(int i)
{
return m_pArray;
}
void Add(T value)
{
if(m_nSize == m_nMaxSize) //s-a ajuns la dimensiune maxima
{
T* pTemp = new T[m_nMaxSize];
memcpy(pTemp, m_pArray, m_nMaxSize * sizeof(T));
delete[] m_pArray;
m_pArray = new T[m_nMaxSize + m_nGrowBy];
memcpy(m_pArray, pTemp, m_nMaxSize * sizeof(T));
delete[] pTemp;

m_pArray[m_nSize] = value;

m_nSize++;
m_nMaxSize+=m_nGrowBy;
}
else
{
m_nSize++;
m_pArray[m_nSize-1] = value;
}
}
int Find(T value)
{
return GetPositionInVector(m_pArray, &value, m_nSize);
}
};

void Test()
{
TypedArray<int>** m_arr;
AlocaMatrice(m_arr, 2, 2);
m_arr[0][0].Add(10);
m_arr[0][0].Add(11);
m_arr[0][1].Add(10);
m_arr[0][1].Add(11);
m_arr[1][0].Add(10);
m_arr[1][0].Add(11);
m_arr[1][1].Add(10);
m_arr[1][1].Add(11);

for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
m_arr[j].RemoveAll();
DealocaMatrice(m_arr, 2);

TypedArray<int> l;
l.Add(1);
l.Add(2);
l.Add(3);
l.Add(4);
l.Add(5);
printf(&quot;%d\n&quot;, l.GetAt(2));
l.Add(6);
l.Add(7);
l.Add(8);
l.RemoveAll();

TypedArray<long> g;
g.Add(9);
g.Add(10);
g.Add(11);
g.Add(12);
g.Add(13);

printf(&quot;%d, %d\n&quot;, g.GetAt(2), g.GetAt(1));
}

int main(int argc, char* argv[])
{
int tmpDbgFlag;
tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
tmpDbgFlag |= _CRTDBG_ALLOC_MEM_DF;
_CrtSetDbgFlag(tmpDbgFlag);

Test();

_CrtDumpMemoryLeaks( );

return 0;
}


s-)

Blessed is he who in the name of justice and goodwill, sheperds the weak through the valley of darkness...
 
it is not correctly what you do:
Code:
T** x;//2D array
//create
x = new T*[y];
for(... to y....) x[i]=  new T[z];
//so far looks ok
using:
l = x[a][b];//for VisualC++ it is incorrect

//the same thing at freeing memory

correctly will be
T* x;
x = new T[y * x];//create
//using, instead of x[a][b]
x + (a * width + b);
//freeing
delete[] x;

VisualC++ does not support such type of allocation/deallocation.

Ion Filipski
1c.bmp
 
Tnx but I solve it other way:

template <typename T>
void AlocaMatrice(T**& aMatrice, unsigned int nCountX, unsigned int nCountY)
{
if (nCountX == 0 || nCountY == 0){aMatrice = 0x0; return;};

aMatrice = new T*[nCountX];
aMatrice[0] = new T[nCountX * nCountY];
for ( unsigned int i = 1; i < nCountX; i++ )
aMatrice = aMatrice[i-1] + nCountY;
/*
for(unsigned int i=0; i<nCountX; i++)
aMatrice = new T[nCountY];
*/
}

template <typename T>
void DealocaMatrice(T**& aMatrice, unsigned int nCountX)
{
if (aMatrice!=0x0 /*NULL*/)
{
/*
for(unsigned int i=0; i<nCountX; i++)
delete aMatrice; //<--here the code stops
*/
delete[] aMatrice[0];
delete[] aMatrice;

aMatrice = 0x0;// NULL fara windows.h
}
}

s-)

Blessed is he who in the name of justice and goodwill, sheperds the weak through the valley of darkness...
 
interesting, doesn't it generate memory leaks?

>>Ioane, fa te rog linkul tau sa lucreze

Ion Filipski
1c.bmp
 
No it does not. Anyway thank you for the (unsingned char*) cast explanation.

There also was a problem in line:
delete (unsigned char*)aMatrice; //<--here the code stops

which shoul have been
delete[] aMatrice;

>> Dar link-ul meu functioneaza, probabil ai nimerit in vreo perioada cand averau probleme cei de la brinkster. Altceva ce mai zici, ce mai faci?

Tnx,

s-)

Blessed is he who in the name of justice and goodwill, sheperds the weak through the valley of darkness...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top