0

I'm trying to implement the following (pseudo-code-python) in C using large numbers:

while i * i < n:
    if n % i:
    i += 1

I came up with the following using the gmp.h library:

#include <stdio.h>
#include <gmp.h>

int main () {
    mpz_t n;
    mpz_t i;
    mpz_t o; // Hold constant mpz "1" for incrementing i
    mpz_t x; // Holds "i * i" each loop

    mpz_set_str(n, "338852330881981183", 10);
    mpz_set_str(i, "2", 10);
    mpz_set_str(o, "1", 10);
    mpz_set_str(x, "4", 10);


    while( mpz_cmp(x, n) < 0 ) {
        mpz_add(i, i, o);
        mpz_pow_ui(x, i, 2);
    }

    mpz_clear(i);
    mpz_clear(n);
    return 0;
}

I don't get any errors when I compile with GCC but when I try to run the program I get the following Aborted. I've never seen this before and don't program much in C let alone using gmp.h and very large numbers.

*** glibc detected *** ./factor: realloc(): invalid old size: 0x00000000004006d0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7fdc1eb7bd76]
/lib/x86_64-linux-gnu/libc.so.6(+0x7c94c)[0x7fdc1eb8194c]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0xf0)[0x7fdc1eb81c60]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_default_reallocate+0x1c)[0x7fdc1ee98a1c]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_realloc+0x3a)[0x7fdc1eeaebba]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_set_str+0x301)[0x7fdc1eeafef1]
./factor[0x400810]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7fdc1eb23ead]
./factor[0x4006f9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 1723311                            /root/Desktop/factor
00600000-00601000 rw-p 00000000 08:01 1723311                            /root/Desktop/factor
01629000-0164a000 rw-p 00000000 00:00 0                                  [heap]
7fdc18000000-7fdc18021000 rw-p 00000000 00:00 0 
7fdc18021000-7fdc1c000000 ---p 00000000 00:00 0 
7fdc1e8ef000-7fdc1e904000 r-xp 00000000 08:01 1445725                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fdc1e904000-7fdc1eb04000 ---p 00015000 08:01 1445725                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fdc1eb04000-7fdc1eb05000 rw-p 00015000 08:01 1445725                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fdc1eb05000-7fdc1ec85000 r-xp 00000000 08:01 1445701                    /lib/x86_64-linux-gnu/libc-2.13.so
7fdc1ec85000-7fdc1ee85000 ---p 00180000 08:01 1445701                    /lib/x86_64-linux-gnu/libc-2.13.so
7fdc1ee85000-7fdc1ee89000 r--p 00180000 08:01 1445701                    /lib/x86_64-linux-gnu/libc-2.13.so
7fdc1ee89000-7fdc1ee8a000 rw-p 00184000 08:01 1445701                    /lib/x86_64-linux-gnu/libc-2.13.so
7fdc1ee8a000-7fdc1ee8f000 rw-p 00000000 00:00 0 
7fdc1ee8f000-7fdc1eef6000 r-xp 00000000 08:01 2240985                    /usr/lib/x86_64-linux-gnu/libgmp.so.10.0.5
7fdc1eef6000-7fdc1f0f6000 ---p 00067000 08:01 2240985                    /usr/lib/x86_64-linux-gnu/libgmp.so.10.0.5
7fdc1f0f6000-7fdc1f0fe000 rw-p 00067000 08:01 2240985                    /usr/lib/x86_64-linux-gnu/libgmp.so.10.0.5
7fdc1f0fe000-7fdc1f11e000 r-xp 00000000 08:01 1445677                    /lib/x86_64-linux-gnu/ld-2.13.so
7fdc1f2fb000-7fdc1f2fe000 rw-p 00000000 00:00 0 
7fdc1f31b000-7fdc1f31d000 rw-p 00000000 00:00 0 
7fdc1f31d000-7fdc1f31e000 r--p 0001f000 08:01 1445677                    /lib/x86_64-linux-gnu/ld-2.13.so
7fdc1f31e000-7fdc1f31f000 rw-p 00020000 08:01 1445677                    /lib/x86_64-linux-gnu/ld-2.13.so
7fdc1f31f000-7fdc1f320000 rw-p 00000000 00:00 0 
7fffa2304000-7fffa2325000 rw-p 00000000 00:00 0                          [stack]
7fffa23b2000-7fffa23b4000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted
3
  • did you try to put the -lgmp option when you compile? it should be like gcc -lgmp. Commented Oct 23, 2014 at 22:38
  • 2
    I wish people who don't read the doc would use the C++ wrapper instead, it is much less error-prone: mpz_class i; mpz_class n("338852330881981183"); while(i*i<n)if(n%i!=0)i+=1;. Commented Oct 24, 2014 at 8:01
  • @MarcGlisse: agreed, but Juicy tagged his question as C, not C++ ! Commented Oct 24, 2014 at 8:18

1 Answer 1

5

You should initialize GMP bigintegers using mpz_init. So your main function should start with

mpz_t n;
mpz_t i;
mpz_t o; // Hold constant mpz "1" for incrementing i
mpz_t x; // Holds "i * i" each loop

mpz_init(n);
mpz_init(i);
mpz_init(o);
mpz_init(x);

BTW, you probably want to output x near the end of main using

mpz_out_str (stdout, 10, x);

before the calls to mpz_clear

Then you should compile with gcc -Wall -Wextra -g yourprog.c -lgmp -o yourprog. Once the program is correctly debugged, you might add -O2 mtune=native to optimize your program.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.