2D std::vector problem

Started by
18 comments, last by NightCreature83 12 years, 9 months ago
Thanks guys for your help. As you see I don't really know what I am doing here :lol:. I will change it so I don't use pointers anymore.

So then, when I want to completely empty that vector from objects I will just have to do what ? pop_back until it is empty, clear ...?

I need to remove those objects from memory while application is running.
Advertisement
coll_box.clear(); is all you need to make coll_box empty. coll_box will still occupy some of the old memory after clear() but you most likely don't have to worry about that.
You can just scope the vector such that it is destroyed when you are finished using it. Re-using objects can be a source of bugs.
I want to clear that coll_box vector, so I can fill it up again with new Vector3 objects if necessary.

During the game, sprites sometimes behave just like a dot, sometimes lines (two dots) or rectangles (4). When switching I want to empty it, and fill with new ones.
So I just need to call clear ?

I have one more question: When I delete a sprite that holds that coll_box, do I need to clear that vector then too in the Sprite destructor ?
When I delete a sprite that holds that coll_box, do I need to clear that vector then too in the Sprite destructor ?
coll_box's destructor frees all it's memory and will be called after the Sprite's destructor so there is no need to clear it in the destructor.

You can just scope the vector such that it is destroyed when you are finished using it. Re-using objects can be a source of bugs.


When you put an object in an STL Container, the container assumes ownership of this object, what this means is that when you push an object into the container it will make a copy of this object. When you call clear on this container it will call the destructor on each element that is in the vector and set the size of the vector back to 0, this is not the capacity which is how much memory the container is actually using.


If a std::vector is part of a class this scope trick won't work on the member and when you want to clear the memory the vector is taking you need to make a new vector with capacity 0 and swap this with the vector in the class. The temporary vector you just created will now scope out and be destroyed and with it it will destroy all the objects it contains, so you don't have to call clear on this temp vector. This is whats known as the "swap trick".




[quote name='AntonioR' timestamp='1310658829' post='4835303']When I delete a sprite that holds that coll_box, do I need to clear that vector then too in the Sprite destructor ?
coll_box's destructor frees all it's memory and will be called after the Sprite's destructor so there is no need to clear it in the destructor.
[/quote]


When an instance gets destroyed all the destructors of the member variables are called when the body of the class that is being destroyed has finished executing. You would normally only provide a destructor implementation if you use dynamic memory in any of the member variables as in they are newed somewhere during the lifetime of this instance, or when you need to release resources that this class is using, think of textures, file handles etc.




Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

I am aware of the swap idiom. Forcing the vector to deallocate the memory isn't necessarily a good idea, especially on a vector of vectors. Reallocations of the "outer" vector cause large amounts of work moving the "inner" vectors, for non-move constructor aware compilers.

If the outer vector is merely clear()ed, it may retain its allocated size, which means that if one starts pushing vectors into it these will likely not cause reallocations for the outer vector. Once the size of the outer vector has "peaked", all allocates will be those performed on the inner vector.

Whether the inner vectors needs to be removed, clear()ed or even left alone isn't obvious from the OP's request. I'm still not sure the purpose of this two dimensional vector of vector of Vector. If we had a better idea of what is the high level goal here?


If a std::vector is part of a class this scope trick won't work...
[/quote]
If the vector is truly temporary, it should not be a member of a class that outlives it. Restructuring the code such that the vector naturally goes out of scope would be better.

Whether the inner vectors needs to be removed, clear()ed or even left alone isn't obvious from the OP's request. I'm still not sure the purpose of this two dimensional vector of vector of Vector. If we had a better idea of what is the high level goal here?


OK, namings probably confuse.

Vector3 object holds x,y,z positions , in coll_box case it holds positions of collision points (which can form a line, a rectangle...). coll_box is a member of Sprite objects.

coll_box is 2D because sprites can have multiple "collision boxes" (for head shots and stuff). Each row in the vector would then be a different collision box, containing points (vector3).

Because the number of collision boxes or points can be changed during the life of the Sprite, I want to remove the "inner vectors" completely and its contents, like they never existed. That would have to leave an empty outer vector that I can fill again.

So, the outer vector that holds the inner ones doesn't need to be removed, just emptied like written above.
If col-boxes always contain exactly four points, a resizable container like a vector is not the best way to represent them.

[source lang="cpp"]
struct box
{
Vector3 left,top,right,bottom;
};

std::vector<box> boxes;

void f()
{
box b;
b.left=Vector3(1,2,3);
// etc

boxes.push_back(b);

// blah blah

boxes.clear(); // but as rip-off says, refactor so lifetime matches usage
}
[/source]

This will avoid a great deal of confusion, reduce the amount of memory allocations and probably be far more cache friendly.

Equally, box could be represented by a centre point and three floats representing the half-dimensions of the box, halving the size of the structure but this is likely irrelevant.

[quote name='rip-off' timestamp='1310660830' post='4835317']
Whether the inner vectors needs to be removed, clear()ed or even left alone isn't obvious from the OP's request. I'm still not sure the purpose of this two dimensional vector of vector of Vector. If we had a better idea of what is the high level goal here?


OK, namings probably confuse.

Vector3 object holds x,y,z positions , in coll_box case it holds positions of collision points (which can form a line, a rectangle...). coll_box is a member of Sprite objects.

coll_box is 2D because sprites can have multiple "collision boxes" (for head shots and stuff). Each row in the vector would then be a different collision box, containing points (vector3).

Because the number of collision boxes or points can be changed during the life of the Sprite, I want to remove the "inner vectors" completely and its contents, like they never existed. That would have to leave an empty outer vector that I can fill again.

So, the outer vector that holds the inner ones doesn't need to be removed, just emptied like written above.
[/quote]

All we are saying is that it is better to have a std::vector< BoundingBox > instead of std::vector< std::vector< Vector3 > > and bounding box can be defined as


struct BoundingBox
{
Vector3 m_corners[4];
}

This would give you a better allocation per collsion box than having another vector in the vector. Besides if you clear the outer vector all your bounding boxes would be gone at that point. Also it increases the maintainability and readability of your code.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

This topic is closed to new replies.

Advertisement