• Advertisement

Archived

This topic is now archived and is closed to further replies.

Expanding array

This topic is 5024 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, I need some help here. I''ve got an array that I want to expand. These are the steps that I can think of in order to do so. Any ideas on how to make this easier without any memory leaks? I would like to just have an array of pointers to copy to instead of all the new/delete business, but I can''t remember how to make an array of empty pointers(if you even can). oldArray 1. create new array with same size as oldArray 2. delete pointers in newArray 3. copy pointers from oldArray into newArray 4. recreate oldArray with new size 5. delete pointers in oldArray 6. copy pointers from newArray into oldArray PS Vectors and Linked Lists won''t work, because I need the speedy fast array access times. Thanks! CD Jesus is Lord!!

Share this post


Link to post
Share on other sites
Advertisement
Using a std::vector would not be any slower than what you are proposing.

Share this post


Link to post
Share on other sites
std::vector does have speedy array access time. Use it. It''s good. Really.

Share this post


Link to post
Share on other sites
One of the reasons I don''t want to use a vector is that it''s a 2D array. A vector in a situation like mine would be harmful instead of helpful.

CD

Jesus is Lord!!

Share this post


Link to post
Share on other sites
You must be thinking of something else, then, because a std::vector is basically a 1 dimensional, resizable, quite fast array.

Share this post


Link to post
Share on other sites
Sorry, worded it incorrectly. I don''t want to use a vector, because the array I need to resize is a 2D array. :]

CD

Jesus is Lord!!

Share this post


Link to post
Share on other sites

std::vector< std::vector< int > > x;


Boom, 2D array.

[edited by - Promit on April 15, 2004 5:32:17 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by CD579
1. create new array with same size as oldArray
2. delete pointers in newArray
3. copy pointers from oldArray into newArray
4. recreate oldArray with new size
5. delete pointers in oldArray
6. copy pointers from newArray into oldArray



You've got some redundancy there. Why not do this:

1. create new array with new size, initialize all pointers to NULL
2. copy the pointers from oldArray into newArray
3. delete [] oldArray, use newArray


// assuming MyClass **oldArray was already declared and set

// up, and that numInArray is how many elements are in

// oldArray.


MyClass **tmpArray;

int numNeeded = numInArray + 10; // we want 10 more


// allocate a new array

tmpArray = new MyClass * [numNeeded];

// copy existing pointers, NULL the rest

for(int i=0;i<numNeeded;i++)
{
if(i < numInOldArray) // first pointers are copied

tmpArray[ i ] = oldArray[ i ];
else // the rest are NULLed

tmpArray[ i ] = NULL;
}

// nuke the old array of pointers, we're using the new one

delete [] oldArray;
oldArray = tmpArray;
numInArray = numNeeded;



[edited by - BriTeg on April 15, 2004 5:38:42 PM]

Share this post


Link to post
Share on other sites
I was thinking of doing that, but when you do this:

tmpArray = new MyClass * [numNeeded];

aren''t you creating numNeeded MyClass''s? Then when you set the pointer to NULL, the memory is still there, but you can''t access it, therefore a memory leak?

At least that''s the way my c++ book explains it. Any thoughts?

CD

Jesus is Lord!!

Share this post


Link to post
Share on other sites
quote:
Original post by CD579
I was thinking of doing that, but when you do this:

tmpArray = new MyClass * [numNeeded];

aren''t you creating numNeeded MyClass''s? Then when you set the pointer to NULL, the memory is still there, but you can''t access it, therefore a memory leak?

At least that''s the way my c++ book explains it. Any thoughts?

Either you have a really bad book, or just misinterpreting it. When you do:

tmpArray = new MyClass * [numNeeded];

You are creating an array of pointers to MyClass. Look at the expression like this:

tmpArray = new (MyClass*)[numNeeded];

And you can see that immediatly outside the left bracket is the type, just as usual.

Share this post


Link to post
Share on other sites
quote:
Original post by CD579
I was thinking of doing that, but when you do this:

tmpArray = new MyClass * [numNeeded];

aren''t you creating numNeeded MyClass''s?



No, see the star in there? That creates an array of numNeeded pointers.

quote:

Then when you set the pointer to NULL, the memory is still there, but you can''t access it, therefore a memory leak?



When the array of pointers is created, the pointers are uninitialized and don''t point to any created objects. The for loop copies the old pointers (from oldArray) into the first part of the new array, and initializes the rest of the pointers (the pointers that you needed more space for) to NULL. Then later when you use the array, you can check each pointer: if the pointer is NULL, you can use it to create a new object, but if the pointer is not NULL you know it points to an already created object.

quote:

Jesus is Lord!!



I agree.

Share this post


Link to post
Share on other sites
Ahhhhh... I see now... Works perfectly for the first array, but a problem for the 2nd dimension. Simple example(The names have been changed to protect the innocent lol):




Obj** Arr;

// init the first dimension
Arr = new obj*[nRows];

// and the second..
for(long r=0; r < nRows; r++){
Arr[r] = new obj[nCols]; // actually creates the objs
}



As you can see, there''s a slight problem resizing the second dimension. Any thoughts on this one?

quote:
I agree.


Good to know I''m not the only one on GameDev who thinks so. :]


CD

Jesus is Lord!!

Share this post


Link to post
Share on other sites
quote:
Original post by CD579
Ahhhhh... I see now... Works perfectly for the first array, but a problem for the 2nd dimension.



I''m not sure what you mean. I didn''t know you wanted to resize the second dimension, or even that there was a second dimension.

You could add a level of pointers, and handle your second dimension as we did for the first. In other words, the first dimension is an array of pointers, and each of these pointers point to an array of pointers (instead of an array of objects), each of which points to an individual object. Then you can resize your second dimension arrays like you did you first dimension array.

I won''t post code in this post, it''s much the same as above. The catch is that your top level variable, instead of being Obj** Arr would be Obj*** Arr. It looks scary, but it''s not really if you break it down.

A simpler, more readable approach might be to split it up, like so:

typedef Obj** Row; // handled as above, a Row is an array of pointers to Objects
Row** Columns; // Columns is an array of pointers to Rows

Now you apply the above resizing algorithm to a Row or a Column separately.

Another option is similar: Create a Row class that internally maintains an array of pointers to objects. Create a Grid class that internally maintains an array of pointers to Rows. Then just for fun, create a GridList class that internally maintains an array of pointers to Grids. Then you will me a master of the pointer, young grasshopper.

Share this post


Link to post
Share on other sites
Ahhh... triple pointers.. Never thought of that. Thanks a bunch man. You''ve helped me out a great deal!

CD

Jesus is Lord!!

Share this post


Link to post
Share on other sites
That was a good link. Ya, I guess being a "ThreeStarProgrammer" isn''t good practice. But when I was learning C/C++, I had trouble understanding pointers and indirection until I forced myself to write some code that dynamically created/manipulated 3-dimensional BYTE arrays, using three stars. I''ve *never* used three-star variables since then (about 12 years of C++ coding), but I learned SO MUCH about pointers by doing that, and now I''m totally comfortable and solid with using pointers of any level of indirection.

So maybe there is a good reason to go through an exercise like this for some people.

Share this post


Link to post
Share on other sites
I might be terribly terribly mistaken...but i remember writing a dynamically-reallocatable array using malloc.

Isn''t there such a thing as realloc?

Share this post


Link to post
Share on other sites

  • Advertisement