I have to create a matrix but with the following requirements:
- create a function for it
- the matrix has to be dynamic allocated inside the function
- the matrix has to be returned as a parameter of the function (function has to be void)
What I tried:
void createMatrix(int n,float** matrix)
{
matrix = (float**)malloc(n * sizeof(float*));
for (int i = 0; i < n; i )
matrix[i] = (float*)malloc(n* sizeof(float));
for (int i = 0; i < n; i )
for (int j = 0; j < n; j )
matrix[i][j] = 0;
}
int main()
{
int n;
FILE* fis;
fis = fopen("fileIn.txt", "r");
if (!fis)
{
printf("File not opened");
return;
}
fscanf(fis, "%d", &n);
fclose(fis);
float** matrix;
createMatrix(n, &matrix);
for (int i = 0; i < n; i )
{
for (int j = 0; j < n; j )
printf("%f ", matrix[i][j]);
printf("\n");
}
return;
}
CodePudding user response:
If you're passing the address of a float ** to a function, the type of the parameter should be float ***. So in the function, change the parameter type to that and use *matrix wherever matrix was used.
void createMatrix(int n, float ***matrix)
{
*matrix = malloc(n * sizeof(float*));
for (int i = 0; i < n; i )
(*matrix)[i] = malloc(n* sizeof(float));
for (int i = 0; i < n; i )
for (int j = 0; j < n; j )
(*matrix)[i][j] = 0;
}
Note that the casts have also been removed, as casting the return value of malloc is not necessary and can mask other errors in your code.
You also should add error checking after the calls to malloc.
CodePudding user response:
If you are creating the matrix such a way
matrix = (float**)malloc(n * sizeof(float*));
for (int i = 0; i < n; i )
matrix[i] = (float*)malloc(n* sizeof(float));
for (int i = 0; i < n; i )
for (int j = 0; j < n; j )
matrix[i][j] = 0;
and want to return the matrix through a parameter then the function should be declared like
void createMatrix( int n, float ***matrix )
{
*matrix = malloc( n * sizeof( float* ) );
for ( int i = 0; i < n; i )
( *matrix )[i] = malloc( n * sizeof( float ) );
for ( int i = 0; i < n; i )
{
for ( int j = 0; j < n; j )
{
( *matrix )[i][j] = 0;
}
}
}
That is if you are passing the pointer matrix declared in main like
float** matrix;
to the function by reference through a pointer to it
createMatrix(n, &matrix);
then the corresponding function parameter will have the type float ***.
CodePudding user response:
You'll need to change createMatrix as follows:
void createMatrix(int n,float*** matrix)
{
*matrix = (float**)calloc(n,sizeof(float*));
for (int i = 0; i < n; i )
*matrix[i] = (float*)calloc(n,sizeof(float));
}
In order for the caller to be able to see the matrix you create, you have to pass a pointer to it... yes, that is a pointer-to-a-pointer-to-a-pointer. And by using calloc instead of malloc, the initialization to zero is handled for you.
CodePudding user response:
Some things to note:
- Your function is creating a pointer-to-pointer look-up table, not a 2D array. Pointer-to-pointer look-up tables only make sense when we want individually-sized items, which is never the case in a mathematical, square-shaped matrix. All the pointer-to-pointer trick achieves is bloat, slow access and needless complexity. You gain absolutely no advantages from it. For details see Correctly allocating multi-dimensional arrays
- This look-up table is assigned to the local variable
matrixand not returned from the function, which is a bug and a memory leak.
We can easily fix these bugs and design mistakes if you can drop those requirements you listed. Then there's a much better standard C function for all of this called calloc.
Usage:
size_t fx = 5;
size_t fy = 3;
float (*fmat)[fy] = calloc( 1, sizeof(float[fx][fy]) );
...
free(fmat);
This is much faster than your function, it doesn't come with needless type-generic programming, it allocates a true 2D array in contiguous memory which gives data cache coherence and it sets all data items to zero.
