c++ - 在构造函数中初始化 <random> 类会导致段错误

标签 c++ c++11 random

在下面的代码中,RandomCharSource应该只是根据请求返回一个随机字符。它的构造函数正在初始化一个 mt19937 , uniform_int_distribution<int>和一个 random_device 。但是,当我实例化对象时,出现段错误。

当我在 bar() 中手动创建这些随机类时下面的函数,工作正常。

我做错了什么?这里是否存在初始化顺序问题?我正在使用 GCC 4.7.3。

#include <random>
#include <iostream>

class RandomCharSource
{
public:
    explicit RandomCharSource() : _re{_rd()}, _dist{0, 255} {};
    inline char get_next_char() { return _dist(_re); };
private:
    std::mt19937 _re;
    std::uniform_int_distribution<int> _dist;
    std::random_device _rd;
};

void foo()
{
    RandomCharSource s;
    std::cout << s.get_next_char() << std::endl;
}

void bar()
{
    std::random_device _rd;
    std::mt19937 _re{_rd()};
    std::uniform_int_distribution<int> _dist{0,255};
    std::cout << (char)_dist(_re) << std::endl;
}

int main()
{
    bar(); // Works OK
    foo(); // Segfault

    return 0;
}

最佳答案

这是因为你的初始化顺序

class RandomCharSource
{
public:
    explicit RandomCharSource() : _re{_rd()}, _dist{0, 255} {};
    inline char get_next_char() { return _dist(_re); };
private:
    std::mt19937 _re;
    std::uniform_int_distribution<int> _dist;
    std::random_device _rd;
};

您需要在 _re 之前添加 _rd。成员按照它们在类中声明的顺序进行初始化。因此,当您尝试使用 _rd 初始化 _re 时,_rd 尚未初始化。

来自标准§12.6.2.13(强调我的)

In a non-delegating constructor, initialization proceeds in the following order:

13.1 — First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
13.2 — Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
13.3 — Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
13.4 — Finally, the compound-statement of the constructor body is executed.
[Note: The declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. —end note]

关于c++ - 在构造函数中初始化 <random> 类会导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30671157/

相关文章:

c++ - 有人可以解释这个 C++ 语法吗?

c++ - 如何在 MPI 中创建新类型

c++ - GLSL 中曲面 segmentation 着色器的链接错误

c++ - 使用和不使用 std=c++0x 混合库的任何问题

c++ - 使用 std::shared_ptr 而不是 boost::shared_ptr 时编译失败

c++ - C++11/14/17 中指向方法回调的指针?

c++ - 我可以使用 nullptr 作为 Linux 系统调用参数吗?

python - 有时我的套装是有序的,有时不是(Python)

java - 创建唯一的随机数

c++ - 生成属于指数分布的随机数