[RM2K3] C++ DATA STRUCTURES
Posts
Pages:
1
Is there an easy way to update the size of a Vector? I am using a vector to store condition IDs of the actor, but when I erase an element and resize the vector, each time the condition is removed or expired, that vector's size does not update and I get an incorrect value for the number of elements in the vector.
Example:
Should I just be using a different structure to track conditions? If so, what would be a better method?
Example:
std::vector<int> conditions; int conditionId; bool removeCondition; //... if(removeCondition == true) { removeCondition = false; int oldSize = conditions.size(); int i = std::distance(conditions, std::find(conditions, conditions + conditions.size(), conditionId)); conditions.erase (i); int newSize = conditions.size(); //Why does this still equal the old size? ... }
Should I just be using a different structure to track conditions? If so, what would be a better method?
According to the vector::erase function documentation, the erase function should handle the resizing already, you shouldn't need to call resize. I'm puzzled by this line in your code:
From what I was able to find about std::find with a quick search, the first and second arguments should be iterators to the start and end of your search area, like this:
My guess is you're getting a different value for i than you're expecting, so when it's fed into the erase function, it doesn't find that position and so it doesn't get erased. Hence, your structure stays the same size.
int i = std::find(conditions, conditions + conditions.size, conditionId);
From what I was able to find about std::find with a quick search, the first and second arguments should be iterators to the start and end of your search area, like this:
int i = std::find(conditions.begin(), conditions.end(), conditionId);
My guess is you're getting a different value for i than you're expecting, so when it's fed into the erase function, it doesn't find that position and so it doesn't get erased. Hence, your structure stays the same size.
author=AubreyTheBardThis will not compile which is why I wrote it the other way. Also I added the resize line because erase did not properly resize.int i = std::find(conditions.begin(), conditions.end(), conditionId);
I checked my code again and you're right int i is wrong. The correct line should have been this, but this still doesn't fix my resize issue. I will fix my example to reflect this too.
int i = std::distance(conditions, std::find(conditions, conditions + conditions.size, conditionId));
The example is not my actual code, just a demonstration of what I am trying to do. I don't have anything coded yet, until I can solve the issue. I figured out the issue, but I'm not sure how to fix it. The issue is that I can increase my vector size, but I can't decrease it, no matter which function I use. I think the memory for the vector needs to be reallocated for it to properly resize, but I am not sure how I would achieve this. I am having the same issue with the clear function as well.
Either this way (handles also multiple occurences): https://stackoverflow.com/a/3385251/1871033
No need to call `resize`.
Or this way: https://stackoverflow.com/a/3385249/1871033
#include <algorithm> // ... conditions.erase(std::remove(conditions.begin(), conditions.end(), conditionId), conditions.end());
No need to call `resize`.
Or this way: https://stackoverflow.com/a/3385249/1871033
#include <algorithm> // ... // Note this is an std::vector<int>::iterator and not an int std::vector<int>::iterator pos = std::find(conditions.begin(), conditions.end(), conditionId); if (pos != conditions.end()) // == conditions.end() means the element was not found conditions.erase(pos);
author=CherryThis is much cleaner than what I wrote, but I still have the same issue. I still can't reduce the size of my vectors when using erase and clear. Every time I try to use something like:#include <algorithm> // ... // Note this is an std::vector<int>::iterator and not an int std::vector<int>::iterator pos = std::find(conditions.begin(), conditions.end(), conditionId); if (pos != conditions.end()) // == conditions.end() means the element was not found conditions.erase(pos);
int numConditions = conditions.size()
New Example
std::vector<int> conditions; int currentSize = conditions.size(); //Value of 0 conditions.push_back (50); conditions.push_back (51); currentSize = conditions.size(); //New value of 2 conditions.clear(); currentSize = conditions.size(); //This should be a value of 0, but the value is 2
Hm are you sure?
http://cpp.sh/8daae
As you can see here, the output is zero.
Maybe some other part of your code is the issue?
http://cpp.sh/8daae
As you can see here, the output is zero.
Maybe some other part of your code is the issue?
I might be mistaken, but it does sound like as you call erase on an implicitly copied vector but checking the size on the original one. Perhaps you can show a little more code, so I can provide more useful advises.
I found the issue now. I checked what I was doing, and my pointer is in fact off which resulted in the size value to not be used. I have been coding on and off, so I had to refresh myself on my old code and I did not look carefully enough at the pointers.
Thanks for the feedback everyone.
On another note, should I be using a vector for storing condition Ids or an array? The reason I am using a vector now is because I can easily sort through the elements. This is necessary because I reorder the elements based on the priority in the database manager, which lets me control which condition is displayed in the status/battle menu.
Thanks for the feedback everyone.
On another note, should I be using a vector for storing condition Ids or an array? The reason I am using a vector now is because I can easily sort through the elements. This is necessary because I reorder the elements based on the priority in the database manager, which lets me control which condition is displayed in the status/battle menu.
In fact a std::vector is an array. It's just been dynamically allocated. If you need a resizable array, vector is the right one. Otherwise use std::array (no plain arrays like !).
int[]
If you need a vector, use a vector. Std::vector is in fact THE default Container if you need a dynamically amount of data.
If you simply need a fixed amount of any Kind of data, than you do not need a vector, indeed. But it doesn't change much. As I already said a vector is an array.
If you simply need a fixed amount of any Kind of data, than you do not need a vector, indeed. But it doesn't change much. As I already said a vector is an array.
As I already told you:
* you need a fixed amount of objects of equal type -> go for std::array
* you need a dynamically amount of objects of equal type -> go for std::vector
List is a complete different story. It has other advantages but also harsh tradeoffs. Only use list on contexts where you do not frequently loop over each element. Even if list offers a nice interface on the first look, it shouldn't be your default container.
* you need a fixed amount of objects of equal type -> go for std::array
* you need a dynamically amount of objects of equal type -> go for std::vector
List is a complete different story. It has other advantages but also harsh tradeoffs. Only use list on contexts where you do not frequently loop over each element. Even if list offers a nice interface on the first look, it shouldn't be your default container.
Pages:
1