-2

I am trying to compare a 2 dimensional vector against another 2 dimensional vector.

vector<vector<int> >::iterator rowit1;

for(rowit1 = aboveaveperms.begin(); rowit1 != aboveaveperms.end();rowit1++)
{
    vector<vector<int> >::iterator row2it;

    int s = 0;

    for(row2it = afterave.begin(); row2it != afterave.end();row2it++)
    {
        vector<int> matches (9);

        vector<int>::iterator itset;
        itset = set_intersection(rowit1->begin(),rowit1->end(),row2it->begin() + 1,row2it->end(),matches.begin());
        matches.resize(itset-matches.begin());
        s = matches.size();
        matches.erase(matches.begin(),matches.end());  // my attempt at trying to correct it
    }
}

In the second loop on the first pass matches is created correctly holding 9 zeros. But once it begins the second loop, as soon as it hits the curly bracket, it comes out with 101 million instead of 9. Once it actually hits it's declaration it goes back to the 9 which is proper. I have noticed while debugging that it is holding all of the 2 dimensional vector I am checking against before the declaration corrects it to only holding 9 ints.

idzireit

APPENDUM:

As it has been pointed out I forgot to ask my question. The above code does work as I want the number of matches (between 5 and 9) but because of the erratic behaviour of the vector will it cause a memory leak or sigseg if the other vectors get too big? Also, as whozcraig asked, I have row2it->begin() + 1 because the first element is the game number which is much bigger then the rest of the numbers. The rest of the numbers are sorted though. Example of what I am trying to do is as follows:

perm vector 1

1 3 5 6 7

compare against 4 vectors and count for number of matches in each

5 8 9 10 11

3 7 11 14 18

1 5 6 7 8

so in running through the loop the first match should be 1 second should be 2 and third should be 4. Hope this helps to clarify what I am trying to do.

ADDENDUM 2:

Now that I have my windoze machine up and running and have reinstalled qt creator on it I have run the above code and works fine on windows. I do not get the 101 million elements like I did when running under ubuntu. Why does it work correctly on windoze and not ubuntu ?

idzireit

idzireit
  • 98
  • 1
  • 7
  • 1
    A `vector` is not a `set`. Is it even sorted? – Jesper Juhl Dec 01 '18 at 15:02
  • 1
    So... I read this twice looking for a *question* and still couldn't find one. While putting one together, making a real [mcve] should be easy enough, so please do so. Regarding the posted code, the `erase` call at the bottom is synonymous with `clear()`, so I'm not sure why you didn't just do that. Also, assuming the sequences are *sorted* (a requirement of the api you're using) why not just use an empty target vector to start and a back-inserter ? – WhozCraig Dec 01 '18 at 15:03
  • 1
    @MatthieuBrucher that's iterator differencing. the result should be a magnitude (assuming they're from the same container; it's UB if they're not). – WhozCraig Dec 01 '18 at 15:05
  • BTW, why are you adding `1` at `row2it->begin() + 1` ? – Hiroki Dec 01 '18 at 15:10
  • Sorry was having other problems and was trying to hurry to ask the question. But as you pointed out no question so I am editing it to include the question. As for the row2it->begin() + the vector is sorted for the most part. the first element is the game number which is much higher then the game numbers themselves. the game numbers are sorted but I just needed to skip the game number. – idzireit Dec 01 '18 at 23:29

1 Answers1

1

Firstly, according to https://en.cppreference.com/w/cpp/algorithm/set_intersection, both vectors be intersected must be sorted.

Secondly, you set an initial size of 9 to vector matches, but if the number of intersected elements is greater than 9, then std::set_intersection is writing out of bounds of matches, which may cause an undefined behaviour.

You can execute your code using a memory analyzer as Valgrind in order to detect a possible memory leak. You could use std::back_inserter to avoid this problem:

#include <iterator> // std::back_inserter
vector<int> matches;
std::back_insert_iterator<std::vector<int> > itset(matches);
itset = set_intersection(rowit1->begin(),rowit1->end(),row2it->begin() + 1,row2it->end(), std::back_inserter(matches));
aeroyorch
  • 56
  • 1
  • 6
  • 1
    Tried this approach and when compiling got this error: error: no viable overloaded '=' – idzireit Dec 02 '18 at 15:14
  • I have edited the post to solve the compile error. Anyway, you are not using the returned `itset` so you can obviate it. – aeroyorch Dec 02 '18 at 17:10