0

I'm attempting to read a file into a multidimensional vector, however the program is receiving a 'vector subscript out of range' error upon reaching the last set of data within the file.

The file is formatted as such:

[index between 1-10000][space][rand int between 1-100]

However each index can occur anywhere between 1-50 times, so the file ends up looking something like this:

http://pastebin.com/gvpd1HC0

And everything in-between (I re-wrote the data to be shorter, but the basis is the same).

Here is the code:

ifstream file;
int frequentCatcher[1000];
int numDistItems = 10000;
vector< vector<int> > initialVec(numDistItems, vector<int>(50));

file.open("T25.N0.1K.D10K.txt");

for (int i = 0; i <= 999; i++)      //This loop sets all cells to 0 to begin.
{
    frequentCatcher[i] = 0;
}

if (file.good())
{
    int tracId = 1, tracNum = 0;        //counters to track position in file
    int id, num;                        //tracks actual data contained in file

    while (!file.eof())                 //traverse file
    {
        file >> id;                 //input from file
        file >> num;

        if (tracId == id)
        {
            initialVec[tracId][tracNum] = num;
            tracNum++;              
        }
        else
        {
            tracId++;
            tracNum = 0;        //reset item number each time a new transaction occurs
            initialVec[tracId][tracNum] = num;
            tracNum++;
        }
    }

The error occurs at the moment the id turns to 10000, the vector error is thrown and program crashes. This is after tracNum has been reset to 0, however the file still needs to read all values of 10000 and save them before proceeding.

Dozar
  • 71
  • 2
  • 2
  • 6
  • 1
    You should read about `while (!file.eof()` [is bad](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). – Thomas Matthews Dec 12 '15 at 18:59
  • 1
    Why didn't you just call `push_back` in your loop, instead of assuming that your vector was big enough to hold all the data? Even with the `eof()` issue mentioned by @ThomasMatthews, reading into a vector shouldn't be done in the manner you're doing it. If you really expected 10,000, use `push_back` and then test the size once you're read in all the data. – PaulMcKenzie Dec 12 '15 at 19:02
  • I attempted to replace while (!file.eof()) with while (file >> id) and that led to the same error. When using push.back, I would remove the size parameters, though would the syntax be the same as a normal vector with something along the lines of : initialVec[tracId][tracNum].push_back(num)? – Dozar Dec 12 '15 at 19:05
  • @Dozar The better container would be a `std::map`, as outlined in the answer, not a 2d `vector`, where you have no idea what range the first dimension may have. Even with your attempt, you never checked if `tracId` or `tracNum` are in range before you set your vector item. You should really program defensively, and never assume what your input will be. – PaulMcKenzie Dec 12 '15 at 19:09

1 Answers1

0

The problem here is the assumption that vector[i][j] already exists. With vectors, they are empty until you reserve some slots or push an item into the vector.

A vector of vectors may not be the best data type because you don't know the range of keys before hand. If you see an index order of 1, 5, 3, 2, 4, you will have problems because they are not contiguous.

IMHO, a better solution would be a std::map<int, vector<int> >. The map is better suited for sorting when the range of keys is unknown or not in sorted order. With a map, you can test whether an index (key) exists or not. If the key doesn't exist, you can create a new vector and insert it into the map along with the key.

If the key does exist, you push_back the value into the vector.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154