简体   繁体   中英

segmentation fault using nested vectors

I stumbled upon the following code segment somewhere to create a list of random numbers in a certain interval:

#include <vector>
#include <iostream>
#include <math.h>
struct gen_rand_pos{
  double factor;
  public:
    gen_rand_pos(double r=1.0): factor(r/RAND_MAX)
    {}
    double operator()(){
        return rand()*factor;
    }
};

int main(){
  int N = 5;
  std::vector<double> result(N);
  std::generate_n(std::back_inserter(result), N, gen_rand_pos(1.0));
  std::cout << result[0] << std::endl;
}

It works perfectly fine. I tried to take this one step further and do the same, but this time creating a list(vector) of random unit vectors, uniformly distributed on the sphere. Here is my go at this:

double l2_norm(std::vector<double> const& u) {
    double accum = 0.;
    for (double x : u) {
        accum += x * x;
    }
    return sqrt(accum);
}

struct gen_rand_vec{
  double factor;
  public:
    gen_rand_vec(): factor(2.0/RAND_MAX)
    {}
  std::vector<double> operator()(){
    std::vector<double> result = {rand()*factor-1,rand()*factor-1,rand()*factor-1}; // uniform in each component
    double norm = l2_norm(result);
    std::transform(result.begin(), result.end(), result.begin(),
           std::bind1st(std::multiplies<float>(),1/norm)); // normalize the vector
    return result;
  }
};

However if I now try to construct it in the same manner:

int main(){
  int N = 5;
  std::vector<std::vector<double>> result2(N);
  std::generate_n(std::back_inserter(result2), N, gen_rand_vec());
  std::cout << result2[0][0] <<std::endl;
}

I get a segmentation error. Is the problem lying in the back_inserter or am I doing something completely wrong? I can't figure out. I checked the construction of the single vectors and they work just fine, so the mistake has to lie somewhere after that.

Thanks in advance.

Default size of inner vectors for result2 for indices <0,4> is 0, so you cannot access

result2[0][0]   // inner vector doesn't keep any elements

when you call generate_n with back_inserter , you add new vectors to the end of result2 . In this case you can access indices of inner vector for result2[>=5] .

Your problem is quite simple, std::back_inserter is inserting new vectors at the end of result2 . Hence, you cannot access the first element, since it is not initialized. To solve this, just remove the (N) from the initialization of result2 . Example .

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