How to find the number of rows and columns of a dynamically created matrix?

Asked

Viewed 2,933 times

2

Based on my knowledge, I created a function that returns an initialized matrix:

int** initMatriz(int rows, int cols){
    int i,j;
    int** matriz;

    //aloca memoria para todas as linhas
    matriz = (int**) malloc(rows * sizeof(int*));
    for(i=0; i < rows ; i++){
        //para cada linha eu aloco o nmr de colunas
        matriz[i] = (int*) malloc(cols * sizeof(int));
        //inicializa 
        for(j=0 ; j < cols ; j++){
            matriz[i][j] = 0;
        }
    }

    return matriz;
}

At the time of initializing:

int** matriz = initMatriz(rows, cols);

From that point on, how do I find out the number of rows and the number of columns?

1 answer

3


int** matriz = initMatriz(rows, cols);

From that point on, how do I find out the number of rows and the number of columns?

Well, the answer is right there. Just look at the parameters rows and cols and they will give you the answer.

Okay, maybe you want to know how to do this if you no longer have access to the values of rows and cols. And the answer is that you can’t do that, at least not in a portable way. The value of the pointer is a number that tells on which memory address begins the block of memory that has been allocated, but says nothing about its size.

If you know the deep details of your implementation of malloc, maybe you can find this information in the memory allocation tables that are created or some other type of internal information maintained by malloc. However, a solution based on this is inherently nonportable.

The solution adopted in almost all cases includes you encapsulating the pointer to the array and the size of the array allocated together in the same structure for this. This way, you eliminate the fundamental problem that is not having the size of the area allocated along with that area itself. For example:

typedef struct {
    int rows;
    int cols;
    int** pointer;
} Matriz;

Matriz* initMatriz(int rows, int cols) {
    int i, j;

    // Aloca a memória para todas as linhas.
    int **matriz = (int**) malloc(rows * sizeof(int*));
    for (i = 0; i < rows; i++) {
        // Para cada linha, eu aloco o número de colunas.
        matriz[i] = (int*) malloc(cols * sizeof(int));
        // Inicializa.
        for (j = 0; j < cols; j++) {
            matriz[i][j] = 0;
        }
    }
    Matriz *resultado = (Matriz *) malloc(sizeof(Matriz));
    resultado->rows = rows;
    resultado->cols = cols;
    resultado->pointer = matriz;

    return resultado;
}

To destroy an array in order to free up memory:

void freeMatriz(Matriz *matriz) {
    for (int i = 0; i < matriz->rows; i++) {
        free(matriz->pointer[i]);
    }
    free(matriz->pointer);
    free(matriz);
}
  • So Victor appreciated the answer, I was using this structure already, but before I got to use it I had this doubt really, because I found it interesting and I could not solve it in any way. For normal initiated vectors, it is possible to find the number of positions. through the sizeof(vector)/sizeof(int) code, I thought q would work, but when dynamically starting this code no longer serves. But thanks to your explanation you helped me a lot to understand.

  • Only one doubt, the memory release process, I can give the free only in the matrix? free(matriz) or I need to free pointer and then in the matrix?

  • @Skywalker To use the free, the process is simple (although find information explaining this may not be): Everything you received from malloc, you must return with free. If the malloc gave you a pointer x, then you must return that same pointer with free in the future. You should not pass to free something you haven’t received from a malloc. You shouldn’t call the free more than once to some pointer received from malloc. You should not forget to call the free for something received from malloc.

  • Um yes, so I need to give a free for all the columns in a for and then yes to the Pointer, and then to the matrix. right?

  • 1

    @Skywalker I mean, first you give a free(matriz->pointer) and then free(matriz). I edited the answer to show this.

  • perfect, thanks @Victor Stafusa

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.