1

这可能是一个愚蠢的问题,但我看不出我在这里做错了什么。我有课:

#include <sys/time.h>
#include <gsl/gsl_cdf.h>
#include <gsl/gsl_randist.h>
#include <cmath>
#include "randomnumbergenerator.h"

class RandomNumberGenerator
{
    gsl_rng * rn;
public:
    RandomNumberGenerator();
    ~RandomNumberGenerator();
    double univariate();
    void bivariateGaussian(double rho, double &x, double &y);
};

long currentMicroseconds()
{
    struct timeval now;
    gettimeofday(&now, NULL);
    return now.tv_usec;
}

RandomNumberGenerator::RandomNumberGenerator()
{
    const gsl_rng_type * T;


    gsl_rng_env_setup();

    //T = gsl_rng_default;
    T = gsl_rng_mt19937;
    rn = gsl_rng_alloc (T);
    gsl_rng_set(rn,currentMicroseconds());
}

double RandomNumberGenerator::univariate()
{
    return gsl_rng_uniform(rn);
}

void RandomNumberGenerator::bivariateGaussian(double rho, double &x, double &y)
{
    gsl_ran_bivariate_gaussian (rn, 1.0, 1.0, rho, &x, &y);
}

RandomNumberGenerator::~RandomNumberGenerator()
{
    gsl_rng_free (rn);
}

我从这里调用:

double x;
double y;
rng.bivariateGaussian(rho, x, y);

但我得到一个分段错误gsl_ran_bivariate_gaussian (rn, 1.0, 1.0, rho, &x, &y);

任何的想法?

4

5 回答 5

3

检查是否rn真的被分配了。这可能是唯一可能导致分段错误的事情。

我在我的电脑上测试了你的代码,据他们所知,它运行良好。可能是检查 GSL 的安装,他们有一个可以使用的测试套件

于 2010-01-24T19:32:05.537 回答
1

哪个编译器?我假设这rn是 RandomNumberGenerator 的成员变量。您是否在构造函数中将其初始化为 0?您似乎没有检查 gsl_rng_alloc 的错误返回,您可能应该是因为我可以立即看到的唯一可能导致问题的事情是 ifrn没有指向任何有效的调用 segfaulting。

查看手册,gsl_rng_alloc您可以检查它是否返回NULL或 0,如果没有,则抛出异常。例如:

#include <stdexcept>

RandomNumberGenerator::RandomNumberGenerator()
{
    const gsl_rng_type * T;


    gsl_rng_env_setup();

    //T = gsl_rng_default;
    T = gsl_rng_mt19937;
    rn = gsl_rng_alloc (T);
    if (rn == 0) {
        throw ::std::runtime_error("Failed to allocation a random number generator.");
    }
    gsl_rng_set(rn,currentMicroseconds());
}

另外,您是否尝试过编译-O0以关闭所有优化?

于 2010-01-24T19:28:42.873 回答
1

在:

double x;
double y;
rng.bivariateGaussian(rho, x, y);

x 和 y 可能应该是数组而不是单个变量吗?我希望分布产生 N 个值而不是一个(或两个)。

于 2010-01-24T19:40:08.773 回答
0

我不会编程 C++,而是 C。希望这也适用于你。但在 CI 上,有时会使用 GDB 之类的调试器或 Eclipse 中的调试器。我还使用valgrind(我非常喜欢这个工具)来修复内存泄漏/分段错误。我建议您喜欢本教程 ,以更好地了解 valgrind 可以为您做什么。Valgrind 可以做的更多,所以我建议您阅读有关 valgrind/helgrind 的信息。

于 2010-01-24T20:10:54.347 回答
0

谢谢大家的回答。错误出现在我没有粘贴的一段代码中:(我将 RandomNumberGenerator 的实例作为普通参数传递。当我将其更改为作为引用传递时,它开始神奇地工作。

于 2010-01-24T21:21:20.543 回答