0

I'm trying to have a vector of iterators of a list, that will allow me to access or erase a list element in O(1). The use case is on one hand to use the list to define priority (in front() to have the most prioritized item while in back() to have the least prioritized item), but on the other hand, to get a direct access to every list node (so that I can move any item from the middle of the list to back() - for this I need to erase it from the middle of the list). I'm aware that this is probably not possible, but I really want to make the least changes to have the code running, instead of writing an awkward code (e.g. using "pair") to gain the same functionality. I've read posts like: Keeping vector of iterators of the data and Why can't I make a vector of references? And I understand that its probably not possible the way I want it, but I'm sure that its possible to do with least changes.

Here is a sample program:

#include <iostream>
#include <list>
#include <vector>
#include <functional>

using namespace std;

typedef struct _data
{
    int d;
} tData;

typedef list <tData *> tListTest;
typedef vector <tListTest::iterator> tVecTest;

int main()
{
    tListTest mylist;
    tVecTest myvec;
    tData *myData;
    int i;

    for (i=0; i<10; i++) {
        cout << "Iteration " << i << endl;
        cout << "Stage 1" << endl;
        myData = new tData;
        cout << "Stage 2" << endl;
        myData->d = i;
        cout << "Stage 3" << endl;
        tListTest::iterator listIter = mylist.insert(mylist.end(), myData);
        cout << "Stage 4" << endl;
        myvec[i] = listIter;
        cout << "Stage 5" << endl;
    }

    tListTest::iterator listIter = myvec[7];
    cout << "Deleting " << (*listIter)->d << endl;
    delete *listIter;
    mylist.erase(listIter);

    return 0;
}

here is the output:

Iteration 0
Stage 1
Stage 2
Stage 3
Stage 4
Segmentation fault (core dumped)

I've tried to change the vector definition to:

typedef vector <reference_wrapper<tListTest::iterator>> tVecTest;

And the assignment to:

myvec[i] = ref(listIter);

and it didn't help.

Any idea how can I make this code running? I'm pretty sure I'm almost there.

Thanks in advance

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335

1 Answers1

0

A vector has no elements by default, nor any memory allocated to hold the elements. Your line myvec[i] = listIter attempts to access the element i that hasn't been allocated. Change the declaration to tVecTest myvec(10) to pre-allocate 10 elements. Or better yet, change myvec[i] = listIter to myvec.push_back(listIter).

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
  • Hi, thanks a lot for the answer Violet - the first remark about the vector pre-allocation was very useful. I was 100% positive that its done automatically, so I didn't pay any second thought to this point. Regarding the second remark about **listIter**, note that there are 2 of them - one inside the for loop, and one outside. Since its a tester, I didn't invest much time in pretty coding, but the code compiles an run. – user9250533 Jan 22 '18 at 13:17
  • @user9250533: good point, I was being inattentive, sorry for the confusion. Glad my answer was still partially useful. – Violet Giraffe Jan 22 '18 at 16:39