[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:
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:

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=AubreyTheBard
int i = std::find(conditions.begin(), conditions.end(), conditionId);
This will not compile which is why I wrote it the other way. Also I added the resize line because erase did not properly resize.

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

#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=Cherry
#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);
This 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:
int numConditions = conditions.size()
I always get the maximum number of elements that were used in that vector, even after erasing or clearing the vector.

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?
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.



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[]
!).
@DNKpp
Isn't it bad practice to use vectors instead of arrays though?
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.
Is there a rule of thumb when to use an array, vector, list, etc?
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.
Pages: 1