GMP lib: проблема с управлением памятью mpz_clear () после передачи по ссылке и выделения всего с помощью malloc - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь работать с массивом mpz_t. Я передаю два массива set_e1 и set_e2 функции, которая инициализирует их и заполняет их целыми числами mpz_t (которые я называю «подписями» в моем коде).

Как указано в документации, мы может освободить память, выделенную mpz_init (), используя mpz_clear (). Это хорошо работает, когда я очищаю внутри функции, а не если я использую их после функции (free() invalid pointer). Поскольку все распределяется динамически, я должен иметь доступ к нему после функции.

Я не уверен, что я делаю неправильно, и почему mpz_clear работает, если я использую его внутри generate_training_sets, но не, если я использую его в main после вызова generate_training_sets.

Вот код:

unsigned long generate_training_sets(mpz_t *set_e1, mpz_t *set_e2) {
    char        *samples_dir[2] = {SAMPLE_PATH_1, SAMPLE_PATH_2};
    long        nb_samples = 0;
    char        *filename = NULL;
    attributes  *ref_b = load_attributes("out_b");
    attributes  *ref_m = load_attributes("out_m");

    for (size_t i = 0; i < 2; i++) {
        nb_samples += d_nb_files(samples_dir[i]);
    }

    set_e1 = malloc(nb_samples * sizeof(mpz_t));
    set_e2 = malloc(nb_samples * sizeof(mpz_t));

    if (!set_e1 || !set_e2) {handle_error("malloc sets");}

    for (size_t i = 0; i < nb_samples; i++) {
        mpz_init2(set_e1[i], MAX_SIG_SIZE); // MAX_SIG_SIZE 6000
        mpz_init2(set_e2[i], MAX_SIG_SIZE);
    }

    int j = 0;

    for (size_t i = 0; i < 2; i++) {
            mpz_t   *sig_ex = malloc(sizeof(mpz_t));
            mpz_t   *sig_g = malloc(sizeof(mpz_t));

            if (!sig_exports || !sig_5grams) handle_error("Malloc signatures");

            mpz_init(*sig_ex);
            mpz_init(*sig_g);
            get_signature_ex("somepath", ref, *sig_ex);
            get_signature_g("somepath", ref, *sig_g);

            mpz_set(set_e1[j], *sig_ex);
            mpz_set(set_e2[j], *sig_g);


    }
    ref_b->free(ref_b);
    ref_m->free(ref_m);
    return nb_samples;
}

int main(int argc, char const *argv[]) {
    mpz_t           *set_e1;
    mpz_t           *set_e2;
    unsigned long   nb_samples = 0;

    nb_samples = generate_training_sets(set_e1, set_e2);


    // for (size_t i = 0; i < nb_samples; i++) {
    // print_sig(set_e1[i]); // doesn't work outside the function too for some reason?
    // }

    /* clear stuff */
    for (size_t i = 0; i < nb_samples; i++) {
        printf("%ld\n", i);
        mpz_clear(set_e1[i]);
        mpz_clear(set_e2[i]);
    }
    return 0;
}


1 Ответ

0 голосов
/ 28 мая 2020

Решение, которое я нашел, инициализирует mpz_t массив перед тем, как передать его моей функции, используя:

    mpz_t   *set_1 = malloc(nb_samples * sizeof(mpz_t));
    mpz_t   *set_2 = malloc(nb_samples * sizeof(mpz_t));

Это также позволяет использовать для них метод mpz_clear.

...