指向mpz_t数组的指针的双重自由错误

时间:2009-12-12 02:49:34

标签: c pointers malloc gmp double-free

我正在学习libgmp,为此我正在编写一个寻找素数因素的小程序。我的程序调用一个函数,该函数用不同数量的mpz_t整数填充数组,这是我需要返回的给定数字的素数因子。我打算将最后一个元素设置为NULL,所以我知道函数找到了多少个mpz_t整数。

我的问题是我使用指向mpz_t整数的指针数组得到双重自由错误。我已经写了一些示例代码来说明我的问题:

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

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;
}

2和5打印到stdout,因此分配似乎没问题。但我得到下面的双重免费错误:

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]

我仍然完全习惯指针,gcc没有错误,但是我很确定这是错的,我应该做的事情

mpz_init_set_ui(*p[0], 2UL);

而不是:

mpz_init_set_ui(p[0], 2UL);

但这给了我一个编译错误

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’

无论如何,我的问题是:

  1. 我确定我应该在mpz_init_set_ui()调用中取消引用指针,为什么会出错?
  2. 有更好的方法吗?我应该使用链表吗?(我还没有学过链表,我认为数组是最好的,但是如果我真的让事情变得更加困难,请告诉我) 3.创建一个带有指向我的数组的指针的结构和另一个带有我的数组中元素数量的变量并返回指向它的指针是不是更好?
  3. 该平台是linux 32位,只是在相关的情况下。

    这是我刚刚编写的代码,我想修改它,我在堆栈上声明了mpz_t的数组。但是我想让main()成为一个函数:

    #include <stdio.h>
    #include <stdlib.h>
    #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 < pFLen; i++)
        {
            gmp_printf("%Zd ", primeFactors[i]);
        }
        puts("");
    
        mpz_clear(numToFactor);
        mpz_clear(factor);
        return 0;
    }
    

    先谢谢大家,

2 个答案:

答案 0 :(得分:3)

这一行

 mpz_t *p = malloc(5*sizeof(mpz_t*));

可能是你烦恼的原因。您已为mpz_t的5个指针分配了足够的空间,而不是5 mpz_t s。根据mpz_t的大小,你可能会写过数组的末尾等等。

你想说

 mpz_t *p = malloc(5*sizeof(mpz_t));

分配一个5 mpz_t的数组。

答案 1 :(得分:2)

只是你问题的一部分

mpz_t *p = ...;

ppointer to mpz_t; p[0](与*p相同)是mpz_tp[1](与*(p + 1)相同),...

mpz_init_set_ui(*p[1], 5UL); /* error */

p[1]mpz_t。你不能解除它(我认为) 如果您愿意,可以使用以下语法

mpz_init_set_ui(*(p + 1), 5UL);