Ошибка сегментации - PullRequest
       12

Ошибка сегментации

1 голос
/ 24 января 2010

Это, наверное, глупый вопрос, но я не вижу, что я делаю здесь неправильно. У меня есть класс:

#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);

Есть идеи?

Ответы [ 5 ]

3 голосов
/ 24 января 2010

проверьте, действительно ли выделено rn. Вероятно, это единственное, что может вызвать ошибку сегментации.

Я проверил твой код на моем компьютере, он работает нормально, насколько они могут судить. Может быть, проверьте установку GSL, у них есть набор тестов, который вы можете использовать

1 голос
/ 24 января 2010

В:

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

x и y, возможно, должны быть массивами, а не отдельными переменными? Я ожидаю, что распределение будет производить N значений, а не одно (или два).

1 голос
/ 24 января 2010

Какой компилятор? Я предполагаю, что rn является переменной-членом RandomNumberGenerator. Вы инициализируете это к 0 в конструкторе? Похоже, вы не проверяете ошибку, возвращаемую из gsl_rng_alloc, вероятно, так и должно быть, потому что единственное, что я могу сразу увидеть, это может вызвать проблему, если rn не указывает на что-либо действительное при вызове 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, чтобы повернуть все оптимизации?

0 голосов
/ 25 января 2010

спасибо всем за ваши ответы. Ошибка была в куске кода, который я не вставил :( Я передавал экземпляр RandomNumberGenerator как обычный параметр. Когда я изменил его на передачу в качестве ссылки, он начал работать магическим образом.

0 голосов
/ 24 января 2010

Я не программирую на С ++, но C. Надеюсь, это в некотором роде относится и к вам. Но на C я иногда использую отладчик типа GDB или отладчик в Eclipse. Я также использую valgrind (мне очень нравится этот инструмент), чтобы исправить утечки памяти / ошибки сегментации. Я советую вам полюбить этот урок , чтобы лучше понять, что может сделать для вас valgrind. Valgrind может сделать гораздо больше, поэтому я бы посоветовал вам прочитать о valgrind / helgrind.

...