В настоящее время я изучаю libgmp, и с этой целью я пишу небольшую программу, которая находит простые факторы. Моя программа вызывает функцию, которая заполняет массив с различным количеством mpz_t целых чисел, простых факторов заданного числа, которые мне нужно вернуть. Я планирую установить последний элемент в NULL, поэтому я знаю, сколько целых чисел mpz_t обнаружено.двойная бесплатная ошибка с указателем на массив 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 печатаются на стандартный вывод, поэтому распределение, кажется, хорошо. Но я получаю двойную бесплатно ошибку ниже:
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]
Я все еще полностью используется для указателей, и НКУ не дает никаких ошибок, но я абсолютно уверен, что это неправильно, и я должен делать что-то вроде
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’
Во всяком случае, мои вопросы:
- Я уверен, что я должен быть разыменования указателя в mpz_init_set_ui вызова(), почему это так?
- Есть ли лучший способ сделать это? Должен ли я использовать связанный список? (Я еще не изучил связанные списки, я считаю, что массив лучше всего подходит для этого, но если я действительно затрудняю ситуацию, скажите мне) 3. Было бы лучше создать struct с указателем на мой массив и другую переменную с количеством элементов в моем массиве и вместо этого вернуть указатель на это?
Платформа - это 32-разрядная версия Linux на всякий случай.
Вот код, который у меня есть сейчас, который я хочу изменить, объявляю массив mpz_t в стеке. Но я хочу сделать основной() функцию:
#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;
}
Заранее спасибо людям,
могли бы вы опубликовать остальную часть кода? –