So my goal is to malloc a maze struct that contains a 2D array; however, when I try to allocate memory for each "cell" of the 2D array I can't seem to free it properly afterwards. Is there a way that I could malloc the struct in one line or at least in a way that I can easily free the allocated memory with the free_maze function? I've attached my .c file along with the header file that defines the struct. Additionally, I have attached an example of a maze that is contained within a text file.
#include <stdlib.h>
#include "maze.h"
Maze* malloc_maze(int num_rows, int num_cols){
Maze* maze = malloc(sizeof(*maze));
if (maze == NULL){
free(maze);
return NULL;
}
maze -> cells = malloc(sizeof(maze -> cells)*(num_cols));
if (maze -> cells == NULL){
free(maze);
return NULL;
}
for(int i = 0; i < num_cols; i++){
maze -> cells[i] = malloc(sizeof(*(maze -> cells))*(num_rows));
}
maze -> num_rows = num_rows;
maze -> num_cols = num_cols;
return maze;
}
void free_maze(Maze* maze){
free(maze);
}
Maze* read_maze(FILE* fp){
Maze* maze;
char c = fgetc(fp);
int rows = 0;
int cols = 0;
int chars = 0;
while(c != EOF){
chars++;
c = fgetc(fp);
}
rewind(fp);
while(c != '\n'){
cols++;
c = fgetc(fp);
}
rows = chars / cols;
cols--;
maze = malloc_maze(rows, cols);
rewind(fp);
for(int row_count =0; row_count <= rows; row_count++){
for(int col_count = 0; col_count < cols; col_count++){
fseek(fp, (row_count*(cols+1)+col_count), SEEK_SET);
maze -> cells[col_count][row_count] = fgetc(fp);
}
}
maze -> num_rows = rows;
maze -> num_cols = cols;
return maze;
}
bool write_maze(const char* filename, const Maze* maze){
FILE* ha;
ha = fopen(filename, "w");
if(ha == NULL){
return false;
}
rewind(ha);
int rows = maze -> num_rows;
int cols = maze -> num_cols;
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
fputc(maze -> cells[j][i], ha);
}
fputc('\n', ha);
}
fclose(ha);
return true;
}
/////////////////header file//////////////////////////
#ifndef MAZE_H
#define MAZE_H
#define WALL 'X'
#define PATH ' '
#include <stdio.h>
#include <stdbool.h>
typedef struct _Maze {
int num_rows;
int num_cols;
char** cells;
} Maze;
Maze* malloc_maze(int num_rows, int num_cols);
void free_maze(Maze* maze){
__attribute__((nonnull));
}
Maze* read_maze(FILE* fp){
__attribute__((nonnull));
}
bool write_maze(const char* filename, const Maze* maze){
__attribute__((nonnull));
}
///////////////example maze within .txt file/////////////////////
XXXXX XXX
X X
X XXX XXX
X X X X
X X XXXXX
X X
XXXXX XXX