LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C++ Vector, set_difference not changing .size() and other issues (https://www.linuxquestions.org/questions/programming-9/c-vector-set_difference-not-changing-size-and-other-issues-4175516448/)

SparceMatrix 08-26-2014 02:51 PM

C++ Vector, set_difference not changing .size() and other issues
 
I am having some odd problems while working with vectors. After applying set_difference to a vector and then cycling through the result vector, I see that the size() of the old vector has not changed. Furthermore, I am seeing crashes if the first vector is beyond a certain size. The code below is self contained (for my coding environment).

There is some other processes included that may or may not be relevant, I'm not sure.

There is two alternative inputs for vct_diff, the first shows the error in size() and the second causes a crash. Comment out one or the other to see how they both work.

Code:

#include <cstdlib>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

int main(int argc, char** argv) {
   
    int arr_diff[6] = {7,2,19,9,11,8};
    vector<int> vct_diff (arr_diff, arr_diff+6);
   
    // USE THIS BELOW INSTEAD OF ABOVE
    // AND CRASHES " invalid next size (fast) "
   
//    int arr_diff[8] = {7,2,19,9,11,8,21,6};
//    vector<int> vct_diff (arr_diff, arr_diff+8);

    int arr_A[3] = {2,9,7};
    int arr_B[2] = {19,11};

    vector<int> vct_A (arr_A, arr_A+3);
    vector<int> vct_B (arr_B, arr_B+2);
   
    vector<int> vct(0);
    vct.insert(vct.end(), vct_B.begin(), vct_B.end());
    vct.insert(vct.end(), vct_A.begin(), vct_A.end());
   
    cout << "vct = " ;
    for (int w = 0; w < vct.size(); w++)
    {
        cout << vct[w] << ".";
    }
    cout << "\n";
   
    vector<int> srtv(0);
    //srtv.assign(vct.begin(), vct.end());
    srtv = vct;
    sort(srtv.begin(), srtv.end());
    sort(vct_diff.begin(), vct_diff.end());
   
    cout << "srtv = " ;
    for (int w = 0; w < vct.size(); w++)
    {
        cout << srtv[w] << ".";
    }
    cout << "\n";
   
    cout << "vct_diff = " ;
    for (int w = 0; w < vct_diff.size(); w++)
    {
        cout << vct_diff[w] << ".";
    }
    cout << "\n";
   
    cout << "vct.size() = " << vct.size() << "\n";
    cout << "vct after srtv sort = " ;
    for (int w = 0; w < vct.size(); w++)
    {
        cout << vct[w] << ".";
    }
    cout << "\n";
   
    set_difference(vct_diff.begin(), vct_diff.end(), srtv.begin(), srtv.end(), vct.end());
   
    cout << "vct.size() = " << vct.size() << "  WHY DOES THIS NOT CHANGE?\n";
    cout << "vct after set_difference = " ;
    for (int w = 0; w < vct.size() + 2 ; w++)
    // ADD "+ 2"  ABOVE TO SHOW NEED FOR EXTRA COUNTS TO SHOW ADDED INTEGERS.
    {
        cout << vct[w] << ".";
    }
    cout << "\n";
    return 0;
}

Any and all tips or clues would be appreciated.

ntubski 08-26-2014 03:44 PM

Quote:

Originally Posted by SparceMatrix (Post 5227713)
After applying set_difference to a vector and then cycling through the result vector, I see that the size() of the old vector has not changed.

set_difference doesn't change the size of the result vector, it can't (you don't pass a reference to the result vector). You can use a std::inserter, as in the example code for set_difference, here.

SparceMatrix 08-26-2014 04:57 PM

Quote:

Originally Posted by ntubski (Post 5227731)
set_difference doesn't change the size of the result vector, it can't (you don't pass a reference to the result vector). You can use a std::inserter, as in the example code for set_difference, here.

That works. PROBLEM SOLVED.

But it seems really counter-intuitive. You get an iterator back and it appears you do get something added to the vector where you wanted it. What am I missing? Is there some other way of restoring .size() for the vector, or is it that the vector doesn't really exist with added data? Why would you point the result to some place on a vector if you didn't want it added there?

I don't get it.

SparceMatrix 08-26-2014 05:31 PM

Here is the example from cplusplus.com it has a few clues,

http://www.cplusplus.com/reference/a...et_difference/

Code:

// set_difference example
#include <iostream>    // std::cout
#include <algorithm>    // std::set_difference, std::sort
#include <vector>      // std::vector

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0
  std::vector<int>::iterator it;

  std::sort (first,first+5);    //  5 10 15 20 25
  std::sort (second,second+5);  // 10 20 30 40 50

  it=std::set_difference (first, first+5, second, second+5, v.begin());
                                              //  5 15 25  0  0  0  0  0  0  0
  v.resize(it-v.begin());                      //  5 15 25

  std::cout << "The difference has " << (v.size()) << " elements:\n";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Notice that the whole thing revolves around an iterator, "it".

I have yet to really get used to the meaning of the iterator. This, "vct.end()" is not a vector, it is an iterator.

ntubski 08-26-2014 08:02 PM

Quote:

Originally Posted by SparceMatrix
Why would you point the result to some place on a vector if you didn't want it added there?

vct.end() doesn't point to some place on a vector, it points to a point just "beyond" it. The spec says if you write past the end of a vector you get "undefined behaviour" (i.e. anything can happen). In practice, you might get a segfault, or worse: you won't get a segfault.

Quote:

Originally Posted by SparceMatrix
Here is the example from cplusplus.com it has a few clues,

In that example, they make the vector big enough ahead of time so they can be sure there is no memory corruption (and notice they use v.begin(), i.e. inside the vector). It's a bit more awkward, because they have resize it back down again afterwards.


All times are GMT -5. The time now is 06:06 AM.