does new call class constructors?
Printable View
does new call class constructors?
Yes.Quote:
Originally Posted by Mitsukai
Regards,
Paul McKenzie
i have been having some trouble with my array class. when i called Size function. it gave me an memory error(critical send to microsoft crash error window thingie)
it pointed to the function Size at delete[] p_Array;
Code:template<typename _T>
class Array
{
protected:
_T* p_Array;
long p_Size;
public:
Array(long Size = 0)
{
if(Size < 0)
Size = 0;
p_Array = new _T[p_Size = Size];
}
~Array(void)
{
delete[] p_Array;
}
_T& operator[](long ID) const
{
if(ID < 0 || ID > p_Size)
ID = 0;
return(p_Array[ID]);
}
void Resize(long Size)
{
if(Size < 0)
Size = 0;
_T* Array = new _T[p_Size];
Array = p_Array;
delete[] p_Array;
p_Array = new _T[Size];
int X = 0;
while(X <= Size && X <= p_Size)
{
p_Array[X] = Array[X];
++X;
}
delete[] Array;
p_Size = Size;
}
long Size(void) const
{
return(p_Size);
}
void Size(long Size)
{
if(Size < 0)
Size = 0;
>>>>>>>>>>delete[] p_Array;
p_Array = new _T[p_Size = Size];
}
};
IsoMap(long Layers = 0, long Width = 0, long Height = 0)
{
p_Map.Size(Layers);
p_Pos.Size(Layers);
long L = 0;
long X;
while(L <= Layers)
{
p_Map[L].Size(Width);
p_Pos[L].Size(Width);
X = 0;
while(X <= Height)
{
p_Map[L][X].Size(Height);
p_Pos[L][X].Size(Height);
++X;
}
++L;
}
}
Hi Mitsukai,
Though the following is legal C++, it blows up in M$'s implementation (at least in the VC++ 6.0 era):
JeffCode:p_Array = new _T[p_Size = Size /*=0*/];
Also, an n element array is indexed 0 to n-1.
Code:_T& operator[](long ID) const
{
if(ID < 0 || ID > p_Size)
ID = 0;
return(p_Array[ID]);
}
i tried
makes no diffrenceCode:p_Array = new _T[Size]
well it would be better if you uased std::vector.
If you really can't and you have to write your own Array class (for a school exercise) then your best bet is to use a NULL pointer when the size is 0.
nothing is working... itried 1's isntead of 0's but it dint help. i will post more code...
Code:IsoMap<IsoTile> a;
//------------------------------------------------------------------------------------------------
struct IsoTile
{
long Obj;
long Set;
long X;
long Y;
};
//------------------------------------------------------------------------------------------------
template<typename _T>
class IsoMap
{
protected:
Array<Array<Array<_T> > > p_Map;
Array<Array<Array<RECT> > > p_Pos;
public:
IsoMap(long Layers = 0, long Width = 0, long Height = 0)
{
p_Map.Size(Layers);
p_Pos.Size(Layers);
long L = 0;
long X;
while(L <= Layers)
{
p_Map[L].Size(Width);
p_Pos[L].Size(Width);
X = 0;
while(X <= Height)
{
p_Map[L][X].Size(Height);
p_Pos[L][X].Size(Height);
++X;
}
++L;
}
}
CJArray& operator[](long ID) const
{
if(ID < 0 || ID > p_Map.Size())
return(NULL);
return(p_Map[ID]);
}
long Height(void) const
{
return(p_Map[0][0].Size());
}
long Layers(void) const
{
return(p_Map.Size())
}
long Width(void) const
{
return(p_Map[0].Size())
}
};
//------------------------------------------------------------------------------------------------
template<typename _T>
class Array
{
protected:
_T* p_Array;
long p_Size;
public:
Array(long Size = 0)
{
if(Size < 0)
Size = 0;
p_Array = new _T[Size];
p_Size = Size;
}
~Array(void)
{
delete[] p_Array;
}
_T& operator[](long ID) const
{
if(ID < 0 || ID > p_Size)
return((_T)NULL);
return(p_Array[ID]);
}
void Resize(long Size)
{
if(Size < 0)
return;
_T* Array = new _T[p_Size];
Array = p_Array;
delete[] p_Array;
p_Array = new _T[Size];
int X = 0;
while(X <= Size && X <= p_Size)
{
p_Array[X] = Array[X];
++X;
}
delete[] Array;
p_Size = Size;
}
long Size(void) const
{
return(p_Size);
}
void Size(long Size)
{
if(Size < 0)
return;
delete[] p_Array;
p_Array = new _T[Size];
p_Size = Size;
}
};
//------------------------------------------------------------------------------------------------
This sequence of steps is wrong. You should do the following:Code:_T* Array = new _T[p_Size];
Array = p_Array;
delete[] p_Array;
p_Array = new _T[Size];
- create a new array with the new size in a different variable
- copy everything over
- only then delete the old array
you are still calling new with a length of 0.
And don't overuse "Size" by making it both a member function and a local variable.
Hi,
Add an assert to snap the debugger:
Code:Array(long Size = 0)
{
if(Size < 0)
Size = 0;
ASSERT( Size > 0 );
p_Array = new _T[p_Size = Size];
}
im creating a copy of the old array so that i can preserve the old variables and im nto caling Resize anywhere so it shlnt be a rpoblem
error C2065: 'ASSERT' : undeclared identifierQuote:
that might be a problem. the size overloading...Quote:
Originally Posted by NMTop40
nope edited tto lSize, tested
itworked, so why woulndt mine work.Code:int* test = new int[0];
delete[] test;
nothing seems to be solving
No, that's not what your code does. Your code does the following:Quote:
Originally Posted by Mitsukai
Translated into words, this is:Code:_T* Array = new _T[p_Size];
Array = p_Array;
delete[] p_Array;
p_Array = new _T[Size];
int X = 0;
while(X <= Size && X <= p_Size)
{
p_Array[X] = Array[X];
++X;
}
delete[] Array;
1. Create a new array
2. Throw that array away by assigning the pointer to the old array (creating a memory leak)
3. Delete the existing array
4. Create a new array from scratch with the new size
5. Access invalid memory (memory that has been deleted already)
6. Delete the same array as in step 3, which you had already deleted.
Step 2 creates a memory leak. Step 5 is invalid and can lead to crashes, Step 6 will most likely crash.
Do you understand how pointers work in C++? A pointer is just a variable that holds the address to a memory location. Think of it as a piece of paper with the street and house number of a person's address. The data itself lives at the house. In step 1, you are building a new house and note that address down on a piece of paper called Array. In step 2, you take an eraser and erase the address on Array and write a new address on it, namely the address of the hous located at p_Array. So now, you don't know anymore where your newly built house is. This is the memory leak.
In this part of the code, there are three "houses" involved (i.e. three places in memory where data is stored as arrays):
1) The existing array, let's call it A (the "old" p_Array)
2) The one that you create in step 1. Call that B
3) The one you create in step 4, call that C.
So, with these names, let's go over the steps again.
1. Create array B and put its address in the variable Array
2. Array = p_Array, means that you don't know the address of B anymore, since now Array points to A.
3. Delete array A. At this point, you don't have any pointer to a valid array anymore, since A is destroyed, you lost track of B and C hasn't been created yet
4. Create C and put its address in p_Array
5. You try accessing A to copy elements from it to C. This is invalid because A has been destroyed
6. Delete array A again. It's also an invalid operation to delete the same array twice.