Storing Model Data - Arrays or Vectors? (C++)

Started by
6 comments, last by Zahlman 17 years ago
Hey guys, I'm writing a little app at the moment (mainly for learning purposes), which reads in a model file and then draws it to the screen. I'm looking for a little help as to how I should store the data from the model file. The data comes in the format of an IndexedFaceSet, like so: '0 1 2, 1 3 2, 2 3 0, 3 1 0', where the values relate to points, like: '0 0 0, 10 0 0, 5 0 8.3, 5 8.3 2.8'. What I have done in the past (using Java) is store the the sets in a 2D array, where [0]=[0,1,2], [1]=[1,3,2] etc. However since writing it in C++ I've come across a few limitations of arrays. For starters I need to know the size of the array in advance before creating it and there's no .length for the array (the facesets will be different depending on the model), like Java has. Also there doesn't appear to be a .split() or similar command which will seperate the above strings by a comma/space delimiter. I have however seen ways to do that with Vectors. Basically if anyone could give me a little nudge in the direction I should take it would be really helpful as I would rather do this in whatever is the best way. Thanks,
Advertisement
I would work with whatever is easier for you, and makes the best sense. If you are worried about possible performance trade-offs, I always suggest 'code it now, profile later' as the best approach.

I would suggest just an array because it's as simple and complex as you need it to be. As for knowing how many vertices are in this array, the format you're loading has to have that information somewhere. Things like dealing with 3 vertices at a time is trivial.

for(int i = 0; i < num_array_verts/3; i++){    cout << array_verts[i*3] << " " << array_verts[i*3 + 1] << " " << array_verts[i*3 + 2] << ",";}
Moved to For Beginners.

Also, clicky.
Thanks for the very fast replies :) Arrays do seem like a good choice because I am fairly familiar with them and not so much vectors. However I'm still at ends to decide how I could split up the data I have. Like I said above, in Java doing something like str.split(","); would split the above strings into an array based on the comma delimiter. Is there any sort of way to do this in C++ or would it be a case of writing my own split function?

Thanks again,

Edit: Thanks for the link Sneftel, I'll have a read of it now.
Edit2: Thanks ApochPiQ, I'll have a read of it also.
You should use std::vector, and this is why.

vector offers the ability to track the number of contained elements, as well as change the number of elements dynamically; it's fairly similar to Java arrays.

You can also use std::ifstream to easily read the data in from a file and fill the vector automatically.

For string processing, std::string has most of the commonly-needed operations built in. You shouldn't need to do any string processing if the data is just lists of numbers, though; the stream IO classes will take care of that in a much more simple way.

[edit] I am the slowness incarnate.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Definatly use an std::vector.
It looks complicated in the beginning but it's quite simple. you can use it just like an array because the [] operator is overloaded and it will let you do everything that you wanted to do with arrays that you couldn't, like changing the size.
As mentioned in ApochPiQ,s link, arrays are EVIL.
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
A C++ std::vector is much more like a Java array than a C++ array is. It effectively adds one main feature (resizability), while the C++ array is missing several - basically, C++ arrays aren't "real objects" ('first-class types'), and lots of strange things happen when you try to pass them to functions (and you can't return them at all). (Also, std::vector offers bounds checking, but it is usual *not* to use it.)

Also, as you've found, you have to either know the size ahead of time, or use a dynamic allocation. To allow for "polymorphism" of a sort, C++ lets you treat a pointer to dynamically allocated memory as if it were an array name (even if it was a *scalar* dynamic allocation - careful!). This is, as you can probably imagine, very dangerous because there isn't any actual subtyping relationship (and also because dynamic allocations require memory management while trying to 'delete' a local array is a serious error); all that is done is to make array *indexing* equivalent to pointer *arithmetic*.

That said, there are other options as well, depending on your circumstances. (Consider both boost::array and boost::multi_array; I suspect neither is helpful to you this time, but they are both things you should know about.) Also, it is a good idea to wrap up the sets in some kind of structure, no matter what kind of container you put them in.

(Really, I wish Java had allowed for resizable arrays behaving like std::vector. The semantics are quite different from java.util.Vector...)

This topic is closed to new replies.

Advertisement