title: double free error with pointer to array of mpz_t
body: <p>I'm currently learning libgmp and to that end I'm writing a small program which find prime factors. My program calls a function which fills an array with a varying amount of mpz_t integers, prime factors of a given number, which I need to return. I'm planning on setting the last element to NULL, so I know how many mpz_t integers the function found.</p>
  
  <p>My problem is I'm getting double free errors with my array of pointers to mpz_t integers. I've written up some sample code illustrating my problem:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;gmp.h&gt;
  
  int main(void)
  {
      mpz_t *p = malloc(5*sizeof(mpz_t*));
      mpz_init_set_ui(p[0], 2UL);
      mpz_init_set_ui(p[1], 5UL);
      gmp_printf("%Zd %Zd\n", p[0], p[1]);
      mpz_clear(p[0]);
      mpz_clear(p[1]);
      free(p);
      return 0;
  }
  </code></pre>
  
  <p>2 and 5 are printed to stdout, so allocation seems to be fine. But I'm getting the double free error below:</p>
  
  <pre><code>2 5
  *** glibc detected *** ./lol: double free or corruption (out): 0x08e20020 ***
  ======= Backtrace: =========
  /lib/libc.so.6(+0x6b6c1)[0xb77126c1]
  /lib/libc.so.6(+0x6cf18)[0xb7713f18]
  /lib/libc.so.6(cfree+0x6d)[0xb7716f8d]
  /usr/lib/libgmp.so.3(__gmp_default_free+0x1d)[0xb77f53fd]
  /usr/lib/libgmp.so.3(__gmpz_clear+0x2c)[0xb77ff08c]
  ./lol[0x80485e3]
  /lib/libc.so.6(__libc_start_main+0xe6)[0xb76bdb86]
  ./lol[0x80484e1]
  </code></pre>
  
  <p>I'm still getting totally used to pointers, and gcc gives no errors, however I'm fairly sure this is wrong and I should be doing something like</p>
  
  <pre><code>mpz_init_set_ui(*p[0], 2UL);
  </code></pre>
  
  <p>instead of:</p>
  
  <pre><code>mpz_init_set_ui(p[0], 2UL);
  </code></pre>
  
  <p>But that gives me a compiler error</p>
  
  <pre><code>test.c:8: error: incompatible type for argument 1 of ‘__gmpz_init_set_ui’
  /usr/include/gmp.h:925: note: expected ‘mpz_ptr’ but argument is of type ‘__mpz_struct’
  </code></pre>
  
  <p>Anyway, my questions are:</p>
  
  <ol>
  <li>I'm sure I should be dereferencing the pointer in the mpz_init_set_ui() call, why is that wrong?</li>
  <li>Is there a better way of doing this? Should I use a linked list?(I've not learned linked lists yet, I figure an array is best for this but if I'm really making things way more difficult, tell me)
  3.Would it be better to create a struct with a pointer to my array and another variable with the amount of elements in my array and return a pointer to that instead?</li>
  </ol>
  
  <p>The platform is linux 32-bit just in case that's relevant.</p>
  
  <p>Here is the code I have just now, which I want to modify, I declare the array of mpz_t on the stack. But I want to make main() a function:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include "prime.h"
  
  #define MAXFACTORS 100
  
  int main(void)
  {
      mpz_t numToFactor, factor;
      mpz_t result;/* used to pass return values from getPrimeFactor() */
      mpz_t primeFactors[MAXFACTORS];
  
      mpz_init_set_str(numToFactor, "18 446 744 073 709 551 615 436 457 568", 10);
      mpz_init(factor);
      mpz_init(result);
  
      int pFLen = 0;
      mpz_init(primeFactors[pFLen]);
  
      getPrimeFactor(numToFactor, result);
      mpz_set(factor, result);
      while(mpz_cmp_ui(factor, 0UL))
      {
          mpz_set(primeFactors[pFLen], factor);
          pFLen++;
          if(pFLen == MAXFACTORS)
          {
              puts("Ran out of space to store prime factors, quitting...");
          }
          mpz_init(primeFactors[pFLen]);
  
          mpz_divexact(factor, numToFactor, factor);
          mpz_set(numToFactor, factor);
  
          getPrimeFactor(factor, result);
          mpz_set(factor, result);
      }
      mpz_set(primeFactors[pFLen], numToFactor);
      pFLen++;
  
      int i;
      for(i = 0; i &lt; pFLen; i++)
      {
          gmp_printf("%Zd ", primeFactors[i]);
      }
      puts("");
  
      mpz_clear(numToFactor);
      mpz_clear(factor);
      return 0;
  }
  </code></pre>
  
  <p>Thanks in advance people,</p>