Tohar Tohar - 2 months ago 12
C Question

How to allocate a 2D array of pointers to a struct

This is were I got so far,but I don't know if it's right.
This function receives the dimensions of the 2D array (nxn),and allocates it.
flightInfo is the name of the struct.
Will this work?
thanks in advanced

after allocating the array(ignore the method ,since we are not allowed to use the method you proposed) I would like to initialize the struct (I built a function to do it but it didn't work),I tried to do it right after the allocation and kept getting the" Unhandled exception" warning, does it has to do
with the syntax, am I forgetting a '*'?

void flightMatrix()
{
FILE * fpf;
int checkScan,Origin,Dest;
float time,cost;
char flightName[3];
flightInfo *** matrix;


if(!(fpf=fopen("flights.txt","r")))exit(1);

while((checkScan=fscanf(fpf,"%*10c%3d%3d%3c%5f%7f%*",&Origin,&Dest,flightName,&time,&cost))!=EOF)
{
matrix=allocateMatrix(Dest);
matrix[Origin-1][Dest-1]->o=Origin;

}


}

flightInfo*** allocateMatrix(int n)

{ int i,j;
flightInfo*** matrix;

matrix=(flightInfo***)malloc(sizeof(flightInfo **)*n);
for(i=0;i<n;i++)
matrix[i]=(flightInfo **)malloc(sizeof(flightInfo*)*n);

for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
matrix[i][j] = NULL;
}

return matrix;
}

Answer

Technically speaking, this won't create 2D array. The result will be array of pointers, where each one points to different array of pointers to a struct.

The difference is that, memory will be fragmented, so every element will point to some memory location, instead of single continuous memory block.

The common approach for this is to create flatten 2D array:

flightInfo** allocateMatrix(int n)
{
    flightInfo** matrix = malloc(n*n * sizeof(*matrix));
    for (int i = 0; i < n; i++) 
        for (int j = 0; j < n; j++) 
            matrix[i*n + j] = NULL;
    return matrix;
}

If you are forced to use two indices, then you could place matrix as function argument:

void allocateMatrix(int n, flightInfo* (**matrix)[n])
{
    *matrix = malloc(n * sizeof(**matrix));
    for (int i = 0; i < n; ++i) 
        for (int j = 0; j < n; ++j) 
            (*matrix)[i][j] = NULL;
}

The second asterisk is required, because pointers are passed by value, otherwise you would end up with modified local copy of the pointer, that does nothing to matrix from main function.

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

typedef struct flightInfo {
    char airport[30];
    int  altitude;
} flightInfo;

void allocateMatrix(int n, flightInfo* (**matrix)[n])
{
    *matrix = malloc(n * sizeof(**matrix));
    for (int i = 0; i < n; ++i) 
        for (int j = 0; j < n; ++j) 
            (*matrix)[i][j] = NULL;
}

int main()
{
    int n = 10;
    flightInfo* (*matrix)[n];

    allocateMatrix(n, &matrix);

    matrix[0][0] = malloc(sizeof(flightInfo));
    strcpy(matrix[0][0]->airport, "Heathrow");
    matrix[0][0]->altitude = 10000;

    printf("%s, %d\n", matrix[0][0]->airport, matrix[0][0]->altitude);
}

The another way would be to encapsulate the array within a struct.