1

I am creating one application and got stuck with vector "reallocation". What I try to do is pass tuple<string, int, vector<Log> *> where 3rd element is pointer pointing on vector<vector<Log>>. Doing that on this way: Vector <Log> *pointer = &arr[length]; . And when I try to print address it works as expected. Problem is happening when I try this :

(*get<2>(*it)).resize(++get<1>(*it));

Trying to reallocate like (*pointer).resize(); Works

What I am trying to make is tuple (something like relational databases) :

tuple<string, int, vector <Log> *> is unique id, number of entries for that id, pointer to address of first element of that row

So basically I will have tuple with basic info about unique ids, number of rows for each IP and pointer to that specific row.

First time when IP comes it's added to tuple and it's data stored on first place. Each other same IP will be checked in tuple and when it's found it's data need to be stored in next free space (with resizing by 1). Hope it's not too complicated to understand.

Here is code I am currently using : (note that variable a is type Log)

typedef vector<tuple<string, int, vector <Log>*>> lookup_list;

lookup_list lookup;
vector<vector<Log>> arr;
vector <Log> *pointer;
int length = 0;
string ip;

for (int i = 0; i < arr_size; i++){
 ip = a[i].ip_address;

auto it = find_if(lookup.begin(), lookup.end(), [ip](const tuple<string, int, vector <Log>*>& e){
     return get<0>(e) == ip;
});

if (it == lookup.end()){
   arr.resize(length + 1);
   arr[length].resize(1);
   pointer = &arr[length];
   arr[length][0] = a[i];
   lookup.push_back(tuple<string, int, vector <Log> *>(ip, 1, pointer));
   length++;
}
else {
   get<1>(*it)++;
   (*get<2>(*it)).resize(get<1>(*it));
   (*get<2>(*it))[(get<1>(*it))-1] = a[i];
}

Error I am getting is basically either trying to access memory that is out of bounds or _Xlength_error("vector too long");

Should note that this happens on first IP that is same size, so not sure why that error is triggered...

PaulMcKenzie
  • 31,493
  • 4
  • 19
  • 38
Aljosa
  • 11
  • 1
  • 3
    `pointer = &arr[length];...lookup.push_back(tuple *>(ip, 1, pointer));` -- You should not store pointers to vector items, as your code is attempting to do. If the vector is resized, those pointer values can become invalidated. – PaulMcKenzie Apr 24 '19 at 21:09
  • [Possible duplicate](https://stackoverflow.com/questions/27735754/validity-of-pointers-to-internal-data-structure-when-reallocating-a-stdvector) – PaulMcKenzie Apr 24 '19 at 21:12
  • @PaulMcKenzie thank you for fast answer. But where can I store those information if they shouldn't be located in vectors? – Aljosa Apr 24 '19 at 21:36
  • Store in the `vector`, but don't use pointers or be very very careful how you use pointers to it. Helpful reading [Iterator invalidation rules](https://stackoverflow.com/questions/6438086/iterator-invalidation-rules). For a `vector` pointers and iterators are pretty much the same thing (the same can't be said for all containers, though). – user4581301 Apr 24 '19 at 21:46
  • @Aljosa -- You could try a `std::list`, where the pointers are not invalidated if items are added or removed (assuming you're not removing the current item you're pointing to). – PaulMcKenzie Apr 25 '19 at 01:29

0 Answers0