2015-06-20 227 views
0

我有一個程序,收到Segmentation Fault 11通知main的簡單性。這裏是我的整個工作的腳本:C++ GMP mpz_init()導致分割錯誤11

#include <iostream> 
#include "gmp.h" 

void 
makeprime() 
{ 
    // *********************** VARIABLE DECLARATION *********************** // 
    // initilize the variables as gmp class instances 
    mpz_t l, rand; 
    unsigned long seed; 
    // perform inits to create variable pointers with 0 value 
    mpz_inits(l, rand); 
    //mpz_init(rand); 

    // calculate the random number floor 
    mpz_ui_pow_ui(l, 2, 199); 

    // initilze the state object for the random generator functions 
    gmp_randstate_t rstate; 
    // initialize state for a Mersenne Twister algorithm. This algorithm is fast and has good randomness properties. 
    gmp_randinit_mt(rstate); 

    // create the generator seed for the random engine to reference 
    gmp_randseed_ui(rstate, seed); 

    /* 
    Function: 
    int mpz_probab_prime_p (const mpz_t n, int reps) 

    Determine whether n is prime. Return 2 if n is definitely prime, return 1 if n is probably prime (without being certain), 
    or return 0 if n is definitely composite. 
    */ 
    do { 
     // return a uniformly distributed random number in the range 0 to n-1, inclusive. 
     mpz_urandomb(rand, rstate, 310); 

     // add the random number to the low number, which will make sure the random number is between the low and high ranges 
     mpz_add(rand, rand, l); 

     gmp_printf("randomly generated number: %Zd\n", rand); 

    } while (!(mpz_probab_prime_p(rand, 25)));   

    // *********************** GARBAGE COLLECTION *********************** // 
    // empty the memory location for the random generator state 
    gmp_randclear(rstate); 
    // clear the memory locations for the variables used to avoid leaks 
    mpz_clear(l); 
    mpz_clear(rand); 
} 

int 
main (void) 
{ 
    makeprime(); 
    return 0; 
} 

好了,現在我會在開頭添加下面兩行主(不改變其他任何有關腳本):

int 
main (void) 
{ 
    mpz_t r;  //added this line 
    mpz_init (r); //and added this line 

    makeprime(); 
    return 0; 
} 

現在我的計劃不正確執行,也不打印或執行makeprime(),而是我得到一個Segmentation Fault 11通知。

什麼給?我在這裏做錯了什麼?

+0

@Galik - 我更新了我的OP以包含我的代碼的其餘部分 – sadmicrowave

+0

如何閱讀「mpz_inits」手冊? (提示:「NULL終止」) –

回答

1

我試圖用gdb來調試你的代碼,它給了我一個段錯誤mpz_inits(l, rand)。然後我修改了這一行,現在它不會給出段錯誤。我會看看我是否能找到段錯誤的原因。

#include <iostream> 
#include "gmp.h" 

void 
makeprime() 
{ 
    // *********************** VARIABLE DECLARATION *********************** // 
    // initilize the variables as gmp class instances 
    mpz_t l, rand; 
    unsigned long seed; 
    // perform inits to create variable pointers with 0 value 

    //mpz_inits(l, rand); 
    mpz_init(rand); 
    mpz_init(l); 

    // calculate the random number floor 
    mpz_ui_pow_ui(l, 2, 199); 

    // initilze the state object for the random generator functions 
    gmp_randstate_t rstate; 
    // initialize state for a Mersenne Twister algorithm. This algorithm is fast and has good randomness properties. 
    gmp_randinit_mt(rstate); 

    // create the generator seed for the random engine to reference 
    gmp_randseed_ui(rstate, seed); 

    /* 
    Function: 
    int mpz_probab_prime_p (const mpz_t n, int reps) 

    Determine whether n is prime. Return 2 if n is definitely prime, return 1 if n is probably prime (without being certain), 
    or return 0 if n is definitely composite. 
    */ 
    do { 
     // return a uniformly distributed random number in the range 0 to n-1, inclusive. 
     mpz_urandomb(rand, rstate, 310); 

     // add the random number to the low number, which will make sure the random number is between the low and high ranges 
     mpz_add(rand, rand, l); 

     gmp_printf("randomly generated number: %Zd\n", rand); 

    } while (!(mpz_probab_prime_p(rand, 25)));   

    // *********************** GARBAGE COLLECTION *********************** // 
    // empty the memory location for the random generator state 
    gmp_randclear(rstate); 
    // clear the memory locations for the variables used to avoid leaks 
    mpz_clear(l); 
    mpz_clear(rand); 
} 

int 
main (void) 
{ 
    makeprime(); 
    return 0; 
} 

編輯:

我看着GMP Documentation和它說以下有關mpz_inits

- Function:無效mpz_initmpz_t X

初始化的x,並將其值設定爲0。

- Function:無效mpz_initsmpz_t X,。 ...

初始化一個空終止列表的mpz_t變量,並將其值設置爲0.

您必須以NULL結束要初始化的變量列表。所以你需要用mpz_inits(l, rand, NULL)代替mpz_inits(l, rand),它工作得很好。

編輯:

你忘了初始化種子。在函數makeprime中,你聲明unsigned long seed;,但不要爲種子分配一個值,因此每次得到相同的數字,因爲種子的值對於每次執行都是相同的。

通常使用系統時間初始化隨機種子。您可以使用

seed = (int) time(NULL); 

在聲明後面初始化種子。一切工作正常然後(不要忘記包括ctimetime.h)。

+0

好吧,我提出了你的建議改變,是的。第一個代碼結構工作正常,沒有任何問題。但是,當我將'mpz_t r;'和'mpz_init(r);'添加到我的'main()'時,'mpz_urandomb'不再正確播種,並且每次程序運行時都會生成相同的編號。 – sadmicrowave

+0

@sadmicrowave看看最新的答案 –

+0

@Galik謝謝。編輯答案。 –