Sign in to follow this  

Making an array with non-default constructors(C++)

This topic is 2790 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

When I make my array like this:
Sector** secPointer;
secPointer = new Sector *[size2nplus1]; 
for ( int i = 0; i < size2nplus1; ++i )
	secPointer[i] = new Sector[size2nplus1];
I can't access a member in my Sector class without crashing and I think it's because Sector only has a constructor with 2 parameters:
Sector::Sector(int setid, World& theWorld)
Everything else seems okay to be accessed within the Sectors, except this array:
float** hMap;
hMap = new float *[theWorld.secsize];	// ** ~ 2 dimensional array
for (int i = 0; i < theWorld.secsize; ++i )
	hMap[i] = new float[theWorld.secsize];

for (int i = 0; i < theWorld.secsize; i++)	{
	for (int j = 0; j < theWorld.secsize; j++)	{
		hMap[i][j] = 0;
	}
}
So you can see I can't have this code in a default constructor with no arguments, because the Sector needs to know the size of the hMap array to use based on the secsize of theWorld argument (theWorld.secsize).

Share this post


Link to post
Share on other sites
Quote:
Original post by PrestoChung
So you can see I can't have this code in a default constructor with no arguments, because the Sector needs to know the size of the hMap array to use based on the secsize of theWorld argument (theWorld.secsize).

Yes indeed. The default constructors do not do what you need: you should make them private.

Use a std::vector to contain your data and construct them explicitly with the appropriate arguments.

Share this post


Link to post
Share on other sites
Speed of access to the hMap array is critical, as it will be accessed many times every frame so I did not want to use std::vector. Because theWorld.secsize does not change during runtime, I may be able to use a fixed size, it will just be inconvenient if I choose to change the size in the future (I guess not so bad, I just have to change 2 extra numbers.)

Share this post


Link to post
Share on other sites
Quote:
Original post by PrestoChung
Speed of access to the hMap array is critical, as it will be accessed many times every frame so I did not want to use std::vector. Because theWorld.secsize does not change during runtime

The fact that std::vector can grow dynamically does NOT imply an efficiency penalty when reading from it.

Share this post


Link to post
Share on other sites
Though if using MSVC, you may get an efficiency penalty reading from it unless you disable the secure SCL functionality.

Share this post


Link to post
Share on other sites
Quote:
Original post by PrestoChung
Speed of access to the hMap array is critical, as it will be accessed many times every frame so I did not want to use std::vector.


That's fine; the vector won't make it any slower to access the memory if you're not resizing it. It will just sit there with, under the hood, a pointer to a single chunk of memory, just the same as the one you would allocate and manage yourself. It's just a more organized way of doing it: the supporting code to deallocate the memory, set up the initial objects (by taking a single "prototype" object and copying it for each element) etc. is already written for you.

However, for a rectangular, 2-dimensional array, you should instead consider boost::multi_array. Making a vector of vectors will cost something in terms of efficiency - and so does your current approach - because each "row" is allocated separately. That means you waste memory for the pointers to rows and can lose performance because of the rows being spread out across the memory space instead of being in a single chunk. The boost::multi_array container is designed to allocate a single chunk but make it behave like a statically-allocated, multi-dimensional array. (It does this by also remembering the dynamic size of each dimension of the array, and using those numbers to do math to index into the storage - plus a bunch of other neat magic that is very difficult to do yourself. How difficult, you say? Well, I tried a few years ago to reproduce the basics of it, and while I had a pretty solid idea of how, I got bored and gave up. ;) )

Share this post


Link to post
Share on other sites
Quote:
Speed of access to the hMap array is critical, as it will be accessed many times every frame so I did not want to use std::vector.
Do you have any evidence that accessing a std::vector is slower than accessing a raw array? Or is that just a guess on your part?

(As noted previously, runtime iterator and range checking can cause some standard library containers to appear to be 'slow' when in debug mode, so be sure you're testing a release build with iterator debugging turned off. With MSVC, for example, _HAS_ITERATOR_DEBUGGING and _SECURE_SCL should both be set to 0.)

Share this post


Link to post
Share on other sites
It was actually a guess on my part.

Thanks for the advice all.

Unfortunately my program is choking on the number of operations needed to update all the maps however (around 9 million i think at current settings, not every frame, but the program is freezing up when i launch it) so i'm going to have to move this up into the Zone class and make it parallel my LOD function to reduce the number of calculations.

Share this post


Link to post
Share on other sites

This topic is 2790 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this