A lambda function which is a member variable crashes

Multi tool use
Multi tool use


A lambda function which is a member variable crashes



The class montecarlo contains lambda as a member variable. This code can be compiled, but will cause "Segmentation fault(core dumped)" in run time. Could you explain how to fix it?


montecarlo


#include<random>
#include<functional>
#include<iostream>

class montecarlo
{
public:
montecarlo(double x_min, double x_max);
std::function<double()> rand;
};

montecarlo::montecarlo(double x_min, double x_max){
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<double> rand_(x_min, x_max);
rand = [&](){return rand_(mt);};
}

int main(){
montecarlo x(0, 1);
std::cout<<x.rand()<<std::endl;
}



And what made me wonder is when I change the constructor's implementation into the code below, it worked:


montecarlo::montecarlo(double x_min, double x_max){
rand = (){return 0;};
}



You would probably know, but let me say that what I want to do is not just using a random functions.




3 Answers
3



You're trying to capture rand_ and mt by reference; they're local objects inside montecarlo::montecarlo, when lambda is called outside montecarlo::montecarlo these local objects have been destroyed and the references stored in lambda object have become dangled.


rand_


mt


montecarlo::montecarlo


montecarlo::montecarlo



You could change it to capture by copy; and note you need to make the lambda mutable to make the invocation on rand_ valid. e.g.


mutable


rand_


rand = [=]() mutable {return rand_(mt);};



This is undefined behavior which should end with Segmentation Fault.
Note that your lambda captures everything by reference and life time variables it captures is limited to constructor processing. So when lambda is used it works on variables which do not exist anymore.



To fix it change lambda to capture variables by copy and it will work.



Or make this variables to be fields of the class.





"undefined behavior which should end with Segmentation Fault" is a non sequitur. By definition, undefined behaviour has no restrictions on what must or should or can happen.
– Caleth
Jul 3 at 8:38





I didn't meant that every UB leads to a crash (most of them don't), but this specific case should end with a crash.
– Marek R
Jul 6 at 10:44



An alternative to copying the generator and distribution in the lambda is making them members of the class. Then they have the same lifetime as rand


rand


class montecarlo
{
std::mt19937 gen;
std::uniform_real_distribution<double> dis;
public:
montecarlo(double x_min, double x_max);
std::function<double()> rand;
};

montecarlo::montecarlo(double x_min, double x_max)
: gen(std::random_device()),
dis(x_min, x_max),
rand([this](){ return dis(gen); })
{}



The name of this class suggests it will be doing other things. I don't recommend that you expand it, but instead split the generating off into it's own class.


class uniform_real_generator
{
std::mt19937 gen;
std::uniform_real_distribution<double> dis;
public:
uniform_real_generator(double x_min, double x_max);
double operator();
}

uniform_real_generator::uniform_real_generator(double x_min, double x_max)
: gen(std::random_device()),
dis(x_min, x_max)
{}

double uniform_real_generator::operator()
{
return dis(gen);
}

class montecarlo
{
// other members
public:
montecarlo(double x_min, double x_max/*, other args */);
uniform_real_generator rand;
}

montecarlo::montecarlo(double x_min, double x_max/*, other args */)
: rand(x_min, x_max) //, other member initialisers
{}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

c,WyVbRneBRvlE kkPHj7 VB21hzVtifGNhUgF j7r8,nkxA0HFcXX3yWbBvdhtjqFud6k9 mM2tUHkvC6
s zAXDbcIWD8yVm,3,oaUUJm,x,Q9 KBz6K2QYt4bgdiNb6exJ2n,TJhN,1

Popular posts from this blog

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?

Create weekly swift ios local notifications