Home > front end >  Problems with memory allocation in C
Problems with memory allocation in C

Time:10-07

I am new to C language and I try to write function to allocate memory for 2d array What am I doing:

void allocate(int **arr, int r, int c) 
{
    **arr = (int **)malloc(r*c*sizeof(int));
}
    int main( void )
{
    int NO_OF_COLS = 0;
    int NO_OF_ROWS = 0;    
    scanf("%d%d", &NO_OF_ROWS, &NO_OF_COLS);

    int **matrix;
    
    allocate(matrix, NO_OF_ROWS, NO_OF_COLS);

    return 0;
}

I have this warning: assignment to 'int' from 'int **' makes integer from pointer without a cast [-Wint-conversion] 8 | **arr = (int **)malloc(rcsizeof(int)); | ^

I understand that I am passing memory to 'matrix' in allocate(), but I don't understand how I can return new memory address and assign it to matrix

I try to change allocate(matrix, NO_OF_ROWS, NO_OF_COLS); to allocate(&matrix, NO_OF_ROWS, NO_OF_COLS); but it still doesn't work

CodePudding user response:

First of all you need to allocate an array of arrays to hold the data. You need to allocate an array to hold N elements of pointer type. Consider this:

int** allocate(int row, int col)
{
    int i;
    int** a = (int**) malloc(row * sizeof(int*));
    if (!a)
        return  0;

    for(i=0; i < row; i  ) {
        a[i] = (int*) malloc(sizeof(int) * col);
    }
    return  a;
}

You need to allocate a to hold N elements that are pointers to int arrays, then loop and allocate the actual array needed ( sizeof(int) * col ) in your use case. So here is in use:

int main()
{
    int** a= allocate(10, 10);
    int i=0, j=0;
    for(i=0; i < 10; i  ) {
        for(j=0; j < 10; j  ) {
            a[i][j] = 42;
        }
    }

    for(i=0; i < 10; i  ) {
        for(j=0; j < 10; j  ) {
            printf("[%d]", a[i][j]);
        }
        puts("");
    }
    return 0;
}

Also you need to write a deallocation function the same way, but first you have to loop trough all elements and free the arrays before freeing the a array in your case. [EDIT]: I haven't added a fail safe check to the second malloc for simplicity. Given that example and that function prototype you need to allocate a 1D array as:

void allocate(int** a, int row, int col)
{
    *a = malloc(sizeof(int) * row * col);
}

But it's a different than allocating arrays of arrays.

CodePudding user response:

Since you can't modify the parameters for allocate, you will need to manually compute the index of each element in the matrix. The following bare-bones program shows how to access each element of a 5 x 5 matrix.

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

void allocate(int **arr, int r, int c)
{
        *arr = malloc(sizeof (int) * r * c); 
}

int main(void)
{
        int *arr = NULL;
        int NO_OF_ROWS = 5, NO_OF_COLS = 5;
        allocate(&arr, NO_OF_ROWS, NO_OF_COLS);

        for (int r = 0; r < NO_OF_ROWS;   r) {
              for (int c = 0; c < NO_OF_COLS;   c) {
                    printf("arr[%d]\n", r * NO_OF_COLS   c); 
              }   
        }   
}

Here, we are actually using a 1-D array. Inside the loop, r * NO_OF_COLS c is responsible for accessing each element. This program will print arr[0], arr[1]...arr[24]. You may use this logic to calculate the index of each element.

Inside main(), arr is just a pointer to an int. When we pass the address of arr to allocate(), we are giving allocate() a chance to modify arr. Then, inside allocate(), we hop to the address that was passed in and lay down the bits returned by malloc.

CodePudding user response:

Here is a simpler form of what you try to do:

void compute_with_matrix(int NO_OF_ROWS, int NO_OF_COLS) 
{
    int matrix[NO_OF_ROWS][NO_OF_COLS];

    /* here work with allocated matrix */  
}
    int main( void )
{
    int NO_OF_COLS, NO_OF_ROWS;    
    scanf("%d %d", &NO_OF_ROWS, &NO_OF_COLS);
    compute_with_matrix(NO_OF_ROWS, NO_OF_COLS);
    return 0;
}
  • Related