2010-01-24 2 views
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);

Любая идея?

+0

@Grzenio, Еще одно предложение это попытка компиляции с '-O0' для поворота всей оптимизации. – Omnifarious

+0

Я думаю, что проверка ошибок valgrind будет полезна. –

ответ

3

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

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

1

Какой компилятор? Я предполагаю, что rn является переменной-членом RandomNumberGenerator. Вы инициализируете его до 0 в конструкторе? Кажется, вы не проверяете возврат ошибки из gsl_rng_alloc, вероятно, вам должно быть, потому что единственное, что я могу увидеть сразу, что может вызвать проблему, - это то, что rn не указывает на что-либо действительное при вызове, который является segfault.

Просмотрев manual for 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

Вложил файл .h. Я использую g ++ (одну из последних версий) в Linux. лучший способ проверить, если rn выделен (и как обращаться, если его нет) – Grzenio

+0

@Grzenio, я не вижу файл .h. – Omnifarious

+0

Я просто слил его сразу после #includes – Grzenio

1

В:

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

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

+0

Извините за беспорядочный вопрос: rng - это RandomNumberGenerator (определено выше). gsl_ran_bivariate_gaussian определен здесь: http://www.gnu.org/software/gsl/manual/html_node/The-Bivariate-Gaussian-Distribution.html – Grzenio

+0

@Grzenio Да, но вы ожидаете одну пару парных разрядов или два массива (для тех из нас, кто не знает, что означает термин «вариация», - это был не самый полезный ручной ввод, который я видел) – 2010-01-24 20:20:02

+0

@Neil Butterworth, в руководстве говорится, что он генерирует пару гауссиан, поэтому я не думаю, что он хочет массивы. – Omnifarious

0

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

0

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

+2

Это не волшебство. 'gsl_rng_free (rn);' освобождает структуру gsl. Конструктор копии по умолчанию просто копирует указатель. Он не выделяет новый конструктор gsl, и вы не определили свой собственный конструктор копирования. Вы должны наследовать от ':: bost :: noncopyable', если у вас есть boost, или объявите ваш RandomNumberGenerator для создания частного конструктора копий и оператора присваивания. – Omnifarious

+0

Приветствия для разъяснения @ Всеобъемлющее, я сделаю это! Его трудно найти голову на C++, потратив пару лет на C# :) – Grzenio

Смежные вопросы