std::vector and operator [] ?

Started by
14 comments, last by Trienco 17 years, 10 months ago
Quote:Original post by Bregma
To tell you the truth, a good optimizing compiler (and the Microsoft one isn't too bad in that respect) will use some common optimization techniques to construct the Mesh object in place in the vector, so only one Mesh ever needs to be constructed and you don;t have to worry about pointers (and their attendant risks).


And if you are REALLY worried about it, just do Mesh.resize(Mesh.size()+1), which is ugly, but pretty much forces the new object to be created in place. Less, but still pretty likely to do that is Mesh.push_back(CMesh());
In both cases you would use Mesh.back() to get to the new object.

But as meshes are usually somewhat big (unless THEY use vectors for their data as well), it's not as critical to have them close to each other in memory for iterating and pointers would be a better choice. If this vector will have multiple pointers to the same mesh, it will be tricky to delete them later, so find a place where you manage a list with pointers to all mesh instances. (Somehow I prefer using a simple template manager class to derive stuff like mesh or texture classes from, especially since loading functions pretty much always follow the scheme "see if we loaded this file already and return pointer to existing data or load it".. and there's not much point in writing it again for all kinds of different ressources).

One thing that you should NOT do. NEVER even think about pulling a stunt like game_object.mesh=&Mesh[x], unless you can be absolutely sure that your vector never grows or has more than enough memory reserved. You don't want it to grow, be moved to a completely different address and invalidate pretty much every single mesh pointer in your program. Use the index instead, even if you dislike the small indirection.
f@dzhttp://festini.device-zero.de
Advertisement
Quote:Original post by _goat
However: Since you're looking ahead to the future - you'd probably want your meshes to be stored in the vector as a pointer. This is because you may want many instances of the same mesh (for example, lots of the same tree) - so instead of giving each new model a new mesh with new vertices/indices, using lots and lots of memory, you could just give each model a pointer to just one mesh, and let them render that. Voila, memory saved!


i've done that some hours ago. i've got an vector container wich contains each mesh, that will be used in the level.
and i've got one container for each object ( since trees will be animated in the future etc.. ) wich just holds the pointer to the right mesh in CMesh.

thanks for your help. i've now a better understanding of these vectors, lists etc..

One thing that you should NOT do. NEVER even think about pulling a stunt like game_object.mesh=&Mesh[x], unless you can be absolutely sure that your vector never grows or has more than enough memory reserved

i am not shure, if my approach is correct. what i do at a level load is:
loop through the file{    search for the next object and check out the model name    search for the model name in Mesh, if it occurs there, get the index, if not    add one model to the end of Mesh and retrieve its index    instance the correct class for the object ( tree, wall etc.. )    give the pointer model[index] to the currently instanced class}


will this work? i haven't tested it with different models, since i my model loader is outdated and needs to read my new model format ( for wich i don't have new models )
i hope it does. if not, what would you do?

btw: after the file is loaded, i will never modify the Mesh vector again, and i will only insert new elements at the end.
Your description of your loading process is a little too ambiguous/general for me to be able to critique with any valid input. It sounds like you won't get any crazy error pointers if you search for the mesh by name and return its index. However:

Quote:Original post by SiS-Shadowman
btw: after the file is loaded, i will never modify the Mesh vector again, and i will only insert new elements at the end.


Warning! The vector class allows you to push_back elements happily because when you run out of space (it works just like an array, remember) it'll allocate a whole new bunch of space that's bigger, copy the old memory to the beginning of that space, and push_back the element into some of the remainder of the new space. You can not

... wait. You said that in your post. I guess you mean you'll take then index of the mesh in the vector? That's garuanteed never to change, so that's all good then. Carry on. Have fun.
[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]
hm, i wanted that each class of an object just holds the pointer to the wanted mesh, but that could be problematic if i understand you right.

now each object has a std::vector<CMesh*> *Mesh pointer and the index for its mesh. i would have preferred the other way, but that is ok. thanks very much :)
I'm not sure I understand why you want a pointer to a vector of mesh pointers?

Are more than one object going to point to the same vector of mesh pointers? Are they sharing mesh lists - so that you want changing one to change all. I realize that may be what you want if you are loading dozens of objects, all of which use the same set of meshes, but just checking. Otherwise it seems you might want std::vector<CMesh*> meshes; instead
Quote:Original post by SiS-Shadowman
hm, i wanted that each class of an object just holds the pointer to the wanted mesh, but that could be problematic if i understand you right.


If you FIRST load all meshes and only start handing out pointers once you don't add anything to the mesh array, then nothing should happen. But if you return pointers to vector elements before it stopped growing, you might run into trouble.

Quote:now each object has a std::vector<CMesh*> *Mesh pointer and the index for its mesh. i would have preferred the other way, but that is ok. thanks very much :)


How many Mesh vectors are there? Or is that just because of some "globals are evil and I want a squeaky clean design" approach?

However, if you only store pointers to meshes and don't put the actual instances in a vector, then they won't change either. Of course then they might end up all over the place and freeing them later on could cause some nice memory fragmentation.

A compromise might be using a deque. Never experimented with it, but if I get the description right, it's basically vector-like chunks. So when you grow a deque beyond it's current capacity, it won't copy anything, but start a new block. Drawback is the hidden indirection, because when you access it by index, it has to do a lookup in a map to find the correct block.

Because they are usually using power of two sizes for the blocks, adjusting the index is a simple index>>x (x/block_size) to find the block and index&(x-1) (x%block_size) to get the index within the block. And actually, I'm not even sure why they would use a map for block addresses, when a vector would do (so I take it, they used map in a general sense meaning "table" and not std::map). However, using direct pointers to the actual data should be safe, so the overhead for random access won't matter much anyway.

In short, a deque is a good compromise, if you want your data aligned next to each other to avoid cache misses (ie. if you intend to iterate of the data a lot), but can't forsee the eventual size and don't want lots of resizing and copying large amounts of stuff around either.
f@dzhttp://festini.device-zero.de

This topic is closed to new replies.

Advertisement