【问题标题】:Segmentation fault with std::uniform_int_distributionstd::uniform_int_distribution 的分段错误
【发布时间】:2019-11-17 21:32:20
【问题描述】:

我有一个包含多个类的程序,其中一些需要随机双精度和整数。在其中一个类中,我定义了一个结构来为随机引擎播种,并能够在需要时通过该结构的对象生成随机实数和整数。 带有类和结构声明的 .hpp 文件如下所示:

struct RNG {
public:
    static std::mt19937 gen;
    static std::uniform_int_distribution<uint32_t> dist_ui;
    static std::uniform_real_distribution<double> dist_d;
    uint32_t r_ui = dist_ui(gen);
    double r_d = dist_d(gen);
private:
    static unsigned seed;
};

class A {
private:
    uint32_t a_;
public:
    A();
};

.cpp 文件如下所示:

#include "A.hpp"

unsigned RNG::seed = 42;
std::mt19937 RNG::gen(RNG::seed);
std::uniform_int_distribution<uint32_t> RNG::dist_ui(1, std::numeric_limits<uint32_t>::max());
std::uniform_real_distribution<double> RNG::dist_d(0.0,1.0);

A::A() {
    RNG* r;
    a_ = r->dist_ui(r->gen);
}

现在,如果我调用 uniform_real_distribution

r->dist_d(r->gen)

一切正常。但是,如果我用

调用 uniform_int_distribution
r->dist_ui(r->gen)

在上面的 sn-p 中,我遇到了分段错误。如果我只使用 int dist 而不是 real 和 int 定义我的结构,或者如果我将 int dist 的边界更改为 [0,100) 或其他什么,也会发生错误。 有谁知道这里发生了什么?感谢您的帮助!

编辑: 如果我访问这样的非静态成员,我会得到同样的错误

RNG r;
a_ = r.r_ui;

【问题讨论】:

  • r 被统一化,它没有指向任何有用的东西 - 访问它是未定义的行为。
  • @Yksisarvinen OP 只通过它访问静态成员,所以应该没问题。起初它也让我失望。
  • @HolyBlackCat 不,不是“应该没问题”。它具有未定义的行为。时期。如果您想访问静态成员,请使用RNG::。不过,根据编辑,这不是问题。
  • 显示您的minimal reproducible example,包括关于分段错误的信息,而不仅仅是您得到一个。

标签: c++ c++11 random segmentation-fault


【解决方案1】:

我有一个猜测。 A 类型的对象也是静态/全局的吗?如果是这样,可能您的问题是因为未定义静态初始化的顺序。因此,您在 dist_ui 初始化之前访问它。

如果不是这样,请发布其余代码(创建A 实例的代码)。

【讨论】:

    【解决方案2】:

    一个最小的可重现示例运行良好,最后,我通过仔细重建我的程序解决了这个问题。这样做,我发现 std::vector 的访问错误,这可能是执行失败的原因之一。 所以,长话短说:我搞砸了我的代码,在发布这个问题之前没有仔细看。 但是,正如 cmets 中所指出的,我不应该像在下面的 sn-p (RNG* r) 中那样访问未初始化的指针,即使它们是静态的。相反,使用范围解析运算符 (::)

    a_ = RNG::dist_ui(RNG::gen)
    

    【讨论】:

      猜你喜欢
      • 2015-10-06
      • 1970-01-01
      • 2012-02-10
      • 2015-09-11
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2017-03-26
      相关资源
      最近更新 更多