-2

I wrote a simple program in C++, using the gmp library, which prints out the modulus of numbers which's digits are composed of 1 (like 1, 11, 111, 1111, 11111, ...) and 2001; problem is when the program reaches 23 digits of 1, I get an error saying Segmantation fault(core dumped). Can you point out where the problem is ? Here is my code :

#include <iostream>
#include <stdio.h>
#include <string>
#include <gmpxx.h>

int main(int argc, char** args){

    mpz_t currNumber;
    mpz_init(currNumber);   
    mpz_set_str(currNumber, "1", 10);

    while(mpz_sizeinbase(currNumber, 10) < 24){
        char* digits =  mpz_get_str(nullptr, 10, currNumber);
        strcat(digits, "1");
        mpz_set_str(currNumber, digits, 10);
        digits = nullptr;


        mpz_t r;
        mpz_init(r);    
        mpz_set_str(r, "1", 20);

        mpz_t divisor;
        mpz_init(divisor);  
        mpz_set_str(divisor, "2001", 20);


        mpz_mmod(r, currNumber, divisor);

        std::cout << "====>" << currNumber << " mod(2001) = " << r << "\n\n\n";

        //Clean up
        mpz_clear(r);
        mpz_clear(divisor);     
    }

    std::cout << "Went until " << mpz_sizeinbase(currNumber, 10) << " digits !" << "\n";

    ///Clean up
    mpz_clear(currNumber);

    return 0;
}

1 Answers1

4

First obvious bug is:

    char* digits =  mpz_get_str(nullptr, 10, currNumber);
    strcat(digits, "1");

The buffer allocated by mpz_get_str does not reliably have room for you to concatenate one extra character onto its contents.

I think you could use:

    char* digits =  mpz_get_str(nullptr, 10, currNumber);
    std::string more_digits = std::string(digits) + "1";
    free(digits);
    mpz_set_str(currNumber, more_digits.c_str(), 10);

1) Since you are in C++, you should use std::string for most string operations and don't need to learn the obscurities of working with C strings.
2) If I understand mpz_get_str correctly (despite never having used it myself) you need to free the buffer it allocated (as I did in this suggested code) to avoid a memory leak.

JSF
  • 5,281
  • 1
  • 13
  • 20