Search code examples
arrayscmultidimensional-arraygmp

Problem of memory allocation after operations on 2D GMP integer matrix


I am trying to use 2D GMP integer matrix. I followed this solution https://stackoverflow.com/a/49987570/7462275.

This is my program

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

int main() {
    const size_t size = 4 ; 
    mpz_t **my_matrix;

    my_matrix=malloc(size*sizeof(mpz_t*));
    my_matrix[0]=malloc(size*size*sizeof(mpz_t));
    for(int i=1;i<size;i++)
        my_matrix[i]=my_matrix[i-1]+(size*sizeof(mpz_t));
   
   
    for (int i=0; i<size;i++)
        for (int j=0; j<size;j++) {
            mpz_init(my_matrix[i][j]);
            mpz_set_ui(my_matrix[i][j],1);
        }


    for (int exponent=1; exponent<20;exponent++)
    
        for (int i=0; i<size;i++)
            for (int j=0; j<size;j++) {
                mpz_mul_ui(my_matrix[i][j],my_matrix[i][j],10);
        }

}

It works as expected. The results of calculation are correct.

But when limit of exponent is increased (e.g. 100) in the for loop ( for (int exponent=1; exponent<100;exponent++) ), a segmentation error(core dumped) happens at running time. How can I solve it ?


Solution

  • This is needlessly complicated, slow and error prone:

    mpz_t **my_matrix;
    
    my_matrix=malloc(size*sizeof(mpz_t*));
    my_matrix[0]=malloc(size*size*sizeof(mpz_t));
    for(int i=1;i<size;i++)
        my_matrix[i]=my_matrix[i-1]+(size*sizeof(mpz_t));
    

    Actually the my_matrix[i-1]+(size*sizeof(mpz_t)); part does pointer arithmetic on type mpz_t so you get offsets of sizeof(mpz_t) times (size*sizeof(mpz_t) bytes, which is all wrong.

    Replace it with:

    mpz_t (*my_matrix)[size] = malloc( sizeof(mpz_t[size][size]) );
    
    if(my_matrix == NULL)
    {
      /* error handling */
    }
    

    (And in the end free(my_matrix);)

    Now you can use my_matrix[i][j] but you actually have a proper 2D array in a contiguously allocated chunk. For details check out Correctly allocating multi-dimensional arrays.