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;
}