delete [ ] array

Started by
11 comments, last by 40 Thieves 23 years, 9 months ago
quick question for you guys: i have something like this: enum TEAM { EMPTY, RED, BLACK, FREE }; TEAM gameBoard[8][8]; in the global scope of my program. When I exit my program (the exit occurs within another function if that matters), do I need to delete my array or no? I tried to delete it with: delete [] &gameBoard and I got no compile errors or build errors, but when i exited my program I get a debug error (in VC++ 6.0) which points to this line of code in dbgdel.cpp (not my file): /* verify block type */ _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); Any help is appreciated (hopefully my stupidity can help others) Thanks in advance for any help. 40 www.databyss.com www.omlettesoft.com "Don''t meddle in the affairs of wizards, for they are subtle and quick to anger."
-40
Advertisement
No you don''t need to delete your array. You never called ''new'' so you don''t need to call delete. The memory for that array is allocated when the program starts and then is released when the program ends, this is all done behind the scenes.

Nate Miller
http://nate.scuzzy.net
thanks for your help... if i wanted to create the array with new... how would i do that?

40

www.databyss.com
www.omlettesoft.com

"Don''t meddle in the affairs of wizards, for they are subtle and quick to anger."
-40
TEAM *gamebaord = new TEAM[size];

I''m not sure how you (or if you can) allocate multi-dimensional arrays.

-Mezz

    enum TEAM { EMPTY, RED, BLACK, FREE };TEAM(*gameboard)[8];    //this DOESNT allocate an array of pointersgameboard = new TEAM[8][8];delete [] gameboard;    


I believe this is correct. You have to be wary when dealing with multidimensional arrays with the new keyword. Also in your example you specified the &address of gameboard, that isn''t needed when you are handling arrays.

Hope this helps...

jumble
-----------
Microsoft patents ones and zeroes - remind you of Hasbro?
jumble-----------
jumble:

Unfortunately, your solution won''t work. A multidimensional array is really just an array of pointers, where each pointer points to a single-dimensional array.

Perhaps I''d better explain with source code - I didn''t get it for many months until I saw a post on gamedev.


40 Thieves:

Here is source code that illustrates how to allocate, use, and deallocate a dynamic 2-dimensional array (i.e., TEAM[8][8]).


enum TEAM { EMPTY, RED, BLACK, FREE };

int main(int argc, char* argv[])
{
const int dimension1 = 8; // size of first dimension you want
const int dimension2 = 8; // size of second dimension you want

// begin to allocate the array
TEAM* gameboard[dimension1]; // array of arrays - that''s a multidimensional array

//////////////////////////////////////////////////////////////////////////////////////////////////////
// here is what the memory looks like so far:
//
// gameboard[0] -> (nothing yet)
// gameboard[1] -> (nothing yet)
// gameboard[2] -> (nothing yet)
// gameboard[3] -> (nothing yet)
// gameboard[4] -> (nothing yet)
// gameboard[5] -> (nothing yet)
// gameboard[6] -> (nothing yet)
// gameboard[7] -> (nothing yet)
//////////////////////////////////////////////////////////////////////////////////////////////////////

for( int x=0; x < dimension2; x++ )
gameboard[x] = new TEAM[dimension2]; // allocate each array

//////////////////////////////////////////////////////////////////////////////////////////////////////
// here is what the memory looks like now:
//
// gameboard[0] -> new TEAM[0], TEAM[1], TEAM[2], TEAM[3], TEAM[4], TEAM[5], TEAM[6], TEAM[7]
// gameboard[1] -> new TEAM[0], TEAM[1], TEAM[2], TEAM[3], TEAM[4], TEAM[5], TEAM[6], TEAM[7]
// gameboard[2] -> new TEAM[0], TEAM[1], TEAM[2], TEAM[3], TEAM[4], TEAM[5], TEAM[6], TEAM[7]
// gameboard[3] -> new TEAM[0], TEAM[1], TEAM[2], TEAM[3], TEAM[4], TEAM[5], TEAM[6], TEAM[7]
// gameboard[4] -> new TEAM[0], TEAM[1], TEAM[2], TEAM[3], TEAM[4], TEAM[5], TEAM[6], TEAM[7]
// gameboard[5] -> new TEAM[0], TEAM[1], TEAM[2], TEAM[3], TEAM[4], TEAM[5], TEAM[6], TEAM[7]
// gameboard[6] -> new TEAM[0], TEAM[1], TEAM[2], TEAM[3], TEAM[4], TEAM[5], TEAM[6], TEAM[7]
// gameboard[7] -> new TEAM[0], TEAM[1], TEAM[2], TEAM[3], TEAM[4], TEAM[5], TEAM[6], TEAM[7]
//
// in other words, we now have an 8x8 array!
//////////////////////////////////////////////////////////////////////////////////////////////////////

// test it!
gameboard[2][7] = RED;
gameboard[1][4] = BLACK;

// now we destroy the array
for( int y=0; y < dimension2; y++ )
delete[] gameboard[y];

//////////////////////////////////////////////////////////////////////////////////////////////////////
// here is what the memory looks like now:
//
// gameboard[0] -> (deleted)
// gameboard[1] -> (deleted)
// gameboard[2] -> (deleted)
// gameboard[3] -> (deleted)
// gameboard[4] -> (deleted)
// gameboard[5] -> (deleted)
// gameboard[6] -> (deleted)
// gameboard[7] -> (deleted)
//
// the array of pointers that we allocated earlier on the stack will simply go out of scope
//////////////////////////////////////////////////////////////////////////////////////////////////////

return 0;
}




- null_pointer
Sabre Multimedia
Mr. Pointer - i''ve just looked up the new keyword in MSDN and it basically says exactly what i said. I put my code into MSVC 6 and it compiled fine... im not sure if it actually worked in practice though.

Hmmm... i''m going to go and make a simple proggy using it.... perhaps the MSVC compiler allows my code?

jumble
-----------
Microsoft patents ones and zeroes - remind you of Hasbro?
jumble-----------
Your code will work jumble because you can create a twodimensional array if one of the array size (the first one I believe) is a constant value.
However if you wan''t to create a completely dynamic twodimensional array you have to go with null_pointer''s solution.
Well, null_pointer is right mostly, but at least it won't be *totally* dynamic. If you want it completely dynamic, do it like the following:

// the pointer to pointer(s) to type TEAMTEAM ** gameboard;//////////////////////////////////////////// at the moment, memory looks like this://// gameboard -> (nothing yet, points to NULL )////////////////////////////////////////////// first _dynamically_ create the array of pointers gameboard = ( TEAM **)malloc( many_times * sizeof( TEAM * ) );//////////////////////////////////////////////////////////////////////////////////////////////////////// here is what the memory looks like now//// gameboard[0] -> (nothing yet)// gameboard[..] -> (nothing yet)// gameboard[n] -> (nothing yet)//////////////////////////////////////////////////////////////////////////////////////////////////////// Afterwards, you have to allocate each field of the array as null_pointer said: for( int x=0; x < as_many_elements_as_you_want; x++ ) {   gameboard[x] = new TEAM; };//////////////////////////////////////////////////////////////////////////////////////////////////////// here is what the memory looks like now://// gameboard[0] -> new TEAM[0], TEAM[..], TEAM[n2]// gameboard[..] -> new TEAM[0], TEAM[..], TEAM[n2]// gameboard[n] -> new TEAM[0], TEAM[..], TEAM[n2]//// in other words, we do now have an n*n2 array//////////////////////////////////////////////////////////////////////////////////////////////////////// now you can access it easily using the standard array style gameboard[0][1] = RED; gameboard[1][0] = FREE; // and so on// now it's up to destroy the whole thing for( x=0; x < as_many_elements_as_you_want; x++ ) {   delete[] gameboard[x]; };//////////////////////////////////////////////////////////////////////////////////////////////////////// here is what the memory looks like now://// gameboard[0] -> (deleted)// gameboard[..] -> (deleted)// gameboard[n] -> (deleted)////////////////////////////////////////////////////////////////////////////////////////////////////////// note that the array of pointers will not go out of scope automatically, we have to free the memory by ourselvesfree( gameboard );// now we're done.   


So now you got a simple dynamical but twodimensional array
btw, it works as well with all other types.
This is similar to null_pointer's version, but it's better if you want, for example, open a map with an unknown size.
Keep in mind that you're able to use pointers to structs here as well, or classes... I think you got the point.

hope this helps,

pi~

p.s.:
sorry null_pointer had to borrow your source. it was a good explanation of the principles but it was not dynamic enough for me
(hell i like playing with pointers and... *access violation -> tried to think whithout allocating memory*)

silly board... ate all my formattings... never use i in loops for arrays... looks strange then...

Edited by - The_[PI]_ehT on July 23, 2000 1:23:46 PM
Jan PieczkowskiBrainwave Studios
Pointers to pointers, mixing malloc with new and running the risk of leaks. Not my kind of thing at all (not anymore anyway). Here's a nicer way (at least I think it is), and you don't need to (explicitly) new or delete anything.

        #include <vector>using std::vector;enum TEAM { EMPTY, RED, BLACK, FREE };int main(int argc, char* argv[]){	const int dimension1 = 8; // size of first dimension you want	const int dimension2 = 8; // size of second dimension you want	//define a vector that holds 'TEAMs	typedef vector<TEAM> TEAM_vector;	//to get a 2 dimensions vector of TEAMs we need to create a vector of team vectors	typedef vector<TEAM_vector> TEAM_vector2D;		//now create the actual 2d vector	//one of the vectors constructors takes a size, and a default value for the type	//so we pass 'dimension1' as the size. For the value of each item in the vector, 	//we pass in a temp TEAM_vector of the size we want (dimension2). each item in 	//the inner vector will have its default constructor called. So for TEAM it'll 	//be set to EMPTY	TEAM_vector2D gameboard(dimension1, TEAM_vector(dimension2));	//////////////////////////////////////////////////////////////////////////////////////////////////////	// here is what the vector looks like after creation	//	// gameboard[0] -> vector<TEAM> - size is dimension2 (8)	// gameboard[1] -> vector<TEAM> - size is dimension2 (8)	// gameboard[2] -> vector<TEAM> - size is dimension2 (8)	// gameboard[3] -> vector<TEAM> - size is dimension2 (8)	// gameboard[4] -> vector<TEAM> - size is dimension2 (8)	// gameboard[5] -> vector<TEAM> - size is dimension2 (8)	// gameboard[6] -> vector<TEAM> - size is dimension2 (8)	// gameboard[7] -> vector<TEAM> - size is dimension2 (8)	//	// in other words, we now have an 8x8 array! <img src="smile.gif" width=15 height=15 align=middle>	//////////////////////////////////////////////////////////////////////////////////////////////////////	// test it!	gameboard[2][7] = RED;	gameboard[1][4] = BLACK;	//the vector will take care of it's own memory so we don't need delete anything.	return 0;}        


Using a vector isn't any slower than using a raw array (apart from the extra temp created for the constructor), and it saves you from needing to delete anything (I don't like 'tidy up' code). Also you can easily change the size of the array at runtime using vector.resize or vector.push_back & vector.pop_back.

PS you don't need to use a typedef, I only used them so I could split up the vector definition a little.

Edited by - Wilka on July 23, 2000 2:56:59 PM

This topic is closed to new replies.

Advertisement