简体   繁体   中英

segmentation fault on inserting vector elements in a vector<vector>

In the constructor of a class called Stamp have two vectors:

  • vector<double> data has a size of data.size()
  • vector<vector <double>> collectedData has a size of [nsamples][data.size()/nsamples]

I need to cycle them in order to have something like this:

  • collectedData[0][0->nsamples] has the first "nsamples" elements of data
  • 'collectedData[1][0->nsamples]' has the second "nsamples" elements of data
  • ...
  • 'collectedData[i][0->nsamples] ' has the i'th "nsamples" elements of data (and '0' if I went over data.size() )

This is the C++ code I'm trying, but I receive a segmentation fault. And I don't understand if it is an algorithmic problem, or a wrong usage of vector problem:

Stamp(vector<double> data, int nsamples) : data(data), nsamples(nsamples){
        long ll = data.size()/nsamples;
        int row;

        //Reserve space in collectedData:
        collectedData.reserve(nsamples);
        for (int i=0;i<nsamples;i++){
            collectedData[i].reserve(ll);
        }

        for (int i=0;i<=data.size();i+=nsamples){
     
            for (int j=0;(j<=nsamples)&&((row*i)<data.size());j++){
                collectedData[i].push_back(data[i]);
            }
            row++;
        }
    }

Firstly, the reserve() function only reserves space without actualy adding elements. You should useresize() to add (or remove) elements.

Secondly, the condition i<=data.size() in the for loop is wrong. You cannot use data[data.size()] . It should be i<data.size() .

Thirdly, there doesn't seem a guarantee that data.size() <= nsamples , so you should add elements again not to cause out-of-range access by collectedData[i] in the second for loop.

Finally, as @molbdnilo pointed out in the comment, the value of non-static local variable row is used without initialization. You should set some proper value to the variable before using that.

Stamp(vector<double> data, int nsamples) : data(data), nsamples(nsamples){
        long ll = data.size()/nsamples;
        int row = 0; // initialize row

        //Reserve space in collectedData:
        if (collectedData.size() < nsamples){
            collectedData.resize(nsamples); // use resize() to add elements
        }
        if (collectedData.size() < data.size()){
            collectedData.resize(data.size()); // use resize() again to allocate enough size
        }
        for (int i=0;i<nsamples;i++){
            collectedData[i].reserve(ll); // using reserve() here because elements are added via push_back() later
        }

        for (int i=0;i<data.size();i+=nsamples){ // use correct condition
     
            for (int j=0;(j<=nsamples)&&((row*i)<data.size());j++){
                collectedData[i].push_back(data[i]);
            }
            row++;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM