I have to store integer values which are mapped to other integers. One way to do it is use a std::map m. But then to retrieve the value using m[int] or m.find(int), will be an order of logN (N is number of elements) time. In my case N is pretty large (upto 2^30). I thought using a std::vector will be faster for access as each key now maps to index of a vector element, which can be accessed in O(1) time. The key is encountered in random order and they may not be contiguous. For e.g., if the vector has size 10, then not all 10 elements are valid and there could only be 6 valid elements and rest I need to fill with -1. I wrote a small program and I’m surprised to find output below:
int main () {
std::vector<int> v;
v.assign(6, -1);
v[3] = 10;
v[10] = 100;
cout << v.size() << v.capacity() << endl ;
cout << v[3] << v[10] << endl;
}
The output seen is size = 6, capacity = 6, V[3] = 10, v[10] = 100. I do not understand how size and capacity are 6, but v[10] has a valid value or I did not encounter a seg. fault. Can someone explain this? My understanding is push_back function dynamically resizes the vector when vector.size > vector.capacity, does operator [] also do this? To be safe, I re-wrote the above code as :
int main () {
std::vector<int> v;
v.assign(6, -1);
int key = getKey();
if (key < v.size())
v[key] = <correct value>;
else {
v.resize(key, -1); // I want to assign -1 to invalid elements
v[key-1] = <correct value>;
}
}
It seems to be working fine, but will it be better to compare key with v.capacity() and then resize the vector.
The size of the vector is just 6. And the accessing index is from 0 to 5. Your first snippet has undefined behavior that you got unlucky that it didn’t break when accessing an index 10. If there is a notion a key association with a value, then associative containers like
std::maporstd::multimapwould be better than a sequence container likestd::vector.