3

对不起,这个问题还没有结束。

我正在尝试编写一个线程安全的随机生成器,但它崩溃了

initstate_r(time(NULL), m_state_buff, sizeof(m_state_buff), &m_data);

我的 gcc 版本:gcc 版本 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>

class RandomGenerator
{
public:
    RandomGenerator()
    {
        initstate_r(time(NULL), m_state_buff, sizeof(m_state_buff), &m_data);
    }

    virtual ~RandomGenerator() {}

public:
    int32_t get_next_int()
    {
#ifdef __GNUC__
        static __thread char stat_buff[512];
        static __thread random_data buff;
        static __thread bool inited = false;

        if (!inited)
        {
               initstate_r(time(NULL), stat_buff, sizeof(stat_buff), &buff);
               srandom_r(time(NULL), &buff);
               inited = true;
        }

        int32_t result = 0;

        random_r(&buff, &result);
        return result;
#endif
    }

private:
    struct random_data m_data;
    char m_state_buff[512];
};


int main()
{
    RandomGenerator r;
    for (int i = 0; i < 100; ++i)
    {
        printf("%d\n", r.get_next_int());
    }
}
4

1 回答 1

0

我相信这与 libc initstate_r() 的错误有关。初始化方法不应该重用缓冲区的值,它应该首先清理它。

当我在调用 initstate_r() 之前清理缓冲区时,分段错误已经消失。

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <string.h>

class RandomGenerator
{
public:
    RandomGenerator()
    {
        memset(m_state_buff, 0, sizeof(m_state_buff));
        memset(&m_data, 0, sizeof(m_data);
        initstate_r(time(NULL), m_state_buff, sizeof(m_state_buff), &m_data);
    }

    virtual ~RandomGenerator() {}

private:
    struct random_data m_data;
    char m_state_buff[512];
};


int main()
{
    RandomGenerator r;
    for (int i = 0; i < 100; ++i)
    {
        printf("%d\n", r.get_next_int());
    }
}
于 2013-05-08T16:20:40.003 回答