I have this matrix initialization function I need: I can generate it without any problems but can't initialize all its values to 0, neither with calloc
or via looping on the matrix elements.
The function is as follows:
int initMTX(int r, int c, int ***MTX) {
int **locMTX = malloc(r * sizeof(int *)), i, j;
for (i = 0; i < r; i ) {
locMTX[i] = (int *)malloc(c * sizeof(int));
}
for (i = 0; i < r; i )
for (j = 0; j < c; j )
locMTX[i][j] = 0;
*MTX = locMTX;
return 1;
}
If needed for context, the entire code is this:
#include <stdio.h>
#include <stdlib.h>
int initMTX(int r, int c, int ***MTX);
void printMTX(int r, int c, int **MTX);
void freeMTX(int r, int **MTX);
int main(void) {
int NBits = 4, NNumbers = 2 ^ NBits, **MTXResults;
initMTX(NNumbers, NBits, &MTXResults);
// code
printMTX(NNumbers, NBits, MTXResults);
freeMTX(NNumbers, MTXResults);
}
int initMTX(int r, int c, int ***MTX) {
int **locMTX = malloc(r * sizeof(int *)), i, j;
for (i = 0; i < r; i ) {
locMTX[i] = (int *)malloc(c * sizeof(int));
}
for (i = 0; i < r; i )
for (j = 0; j < c; j )
locMTX[i][j] = 0;
*MTX = locMTX;
return 1;
}
void printMTX(int r, int c, int **MTX) {
int i, j;
for (i = 0; i < r; i ) {
for (j = 0; j < c; j )
printf("%d ", MTX[i][r]);
printf("\n");
}
}
void freeMTX(int r, int **MTX) {
for (int i = 0; i < r; i )
free(MTX[i]);
free(MTX);
}
I thought I grasped such a thing well by now, but it turns out it is not the case, so I've been stuck for a while.
If possible I would appreciate also knowing where the problem is when using calloc
too.
CodePudding user response:
If your compiler supports Variable Length Arrays, this can be used.
#include <stdio.h>
#include <stdlib.h>
void printMTX(int r, int c, int (*MTX)[c]);
int main(void) {
int NBits = 4;
int NNumbers = NBits * NBits;
int (*MTXResults)[NBits];
if ( NULL == ( MTXResults = calloc( sizeof *MTXResults, NNumbers))) {
fprintf ( stderr, "problem calloc\n");
return 1;
}
printMTX(NNumbers, NBits, MTXResults);
free ( MTXResults);
}
void printMTX(int r, int c, int (*MTX)[c]) {
int i, j;
for (i = 0; i < r; i ) {
for (j = 0; j < c; j ) {
printf("%d ", MTX[i][j]);
}
printf("\n");
}
}
CodePudding user response:
This code fixes the bugs in the code in the question (most notably the typo MTX[i][r]
becomes MTX[i][j]
), and implements freeMTX()
. It also includes the code to recover from a memory allocation failure while creating the matrix.
#include <stdio.h>
#include <stdlib.h>
int initMTX(int r, int c, int ***MTX);
void printMTX(int r, int c, int **MTX);
void freeMTX(int r, int **MTX);
int main(void)
{
int NBits = 4;
int NNumbers = 16;
int **MTXResults;
if (initMTX(NNumbers, NBits, &MTXResults))
{
printMTX(NNumbers, NBits, MTXResults);
freeMTX(NNumbers, MTXResults);
}
else
fprintf(stderr, "failed to allocate %dx%d matrix\n", NBits, NNumbers);
}
int initMTX(int r, int c, int ***MTX)
{
int **locMTX = malloc(r * sizeof(int *));
if (locMTX == 0)
return 0;
for (int i = 0; i < r; i )
{
locMTX[i] = (int *)malloc(c * sizeof(int));
if (locMTX[i] == 0)
{
for (int j = 0; j < i; j )
free(locMTX[j]);
free(locMTX);
return 0;
}
}
for (int i = 0; i < r; i )
{
for (int j = 0; j < c; j )
locMTX[i][j] = 0;
}
*MTX = locMTX;
return 1;
}
void printMTX(int r, int c, int **MTX)
{
for (int i = 0; i < r; i )
{
for (int j = 0; j < c; j )
printf("%d ", MTX[i][j]);
printf("\n");
}
}
void freeMTX(int r, int **MTX)
{
for (int i = 0; i < r; i )
free(MTX[i]);
free(MTX);
}
This code uses the simpler, two allocation scheme outlined in two comments:
#include <stdio.h>
#include <stdlib.h>
int initMTX(int r, int c, int ***MTX);
void printMTX(int r, int c, int **MTX);
void freeMTX(int **MTX);
int main(void)
{
int NBits = 4;
int NNumbers = 16;
int **MTXResults;
if (initMTX(NNumbers, NBits, &MTXResults))
{
printMTX(NNumbers, NBits, MTXResults);
freeMTX(MTXResults);
}
else
fprintf(stderr, "failed to allocate %dx%d matrix\n", NBits, NNumbers);
}
int initMTX(int r, int c, int ***MTX)
{
int **locMTX = malloc(r * sizeof(locMTX[0]));
if (locMTX == 0)
return 0;
int *data = malloc(r * c * sizeof(locMTX[0][0]));
if (data == 0)
{
free(locMTX);
return 0;
}
for (int i = 0; i < r; i )
{
locMTX[i] = data i * c;
for (int j = 0; j < c; j )
locMTX[i][j] = 0;
}
*MTX = locMTX;
return 1;
}
void printMTX(int r, int c, int **MTX)
{
for (int i = 0; i < r; i )
{
for (int j = 0; j < c; j )
printf("%d ", MTX[i][j]);
printf("\n");
}
}
void freeMTX(int **MTX)
{
free(MTX[0]);
free(MTX);
}
The freeing code is much simpler, as is the error recovery while creating the matrix — mainly because there are only two allocations that can fail.