I am struggling with storing value to dynamic array, which was reallocated by realloc() function.
I am creating maze solver program and as a inner representation I want to create 1D array tile_array
of struct tile
elements where every element represents one read character from input file. The struct tile
stores character and additional data such as distance in the array, row and col (abstraction) etc. The maze is represented in struct maze
which contains the tile array
.
I need to dynamically allocate the tile_array
since length of input file is not known. In every iteration of while loop the program creates a struct tile
and assignes it to the end of the 1D array. It works ok till this point. When the array is full, it calls realloc() and continues storing elements to the end of the array. Here is the problem and I dont see the cause. From this point, the printf() function prints NULL for every parameter.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
struct tile
{
// should be one element in tile array
bool visited;
char type; // '#' / ' ' / 'X' / 'o'
size_t distance; // distance in tile_array
size_t row;
size_t col;
struct tile* previous; // pointer to previous tile
};
struct maze
{
struct tile* tile_array; // 1D array of <tile> structs
size_t length; // length of tile_array
size_t *rows_lengths; // [row1_len, row2_len, ...]
size_t row_count; // count of rows used
};
bool maze_create(struct maze *maze, FILE *file)
{
size_t array_length = 4;
// allocate tile_array
struct tile *tile_array = malloc(array_length * sizeof(struct tile));
if (tile_array == NULL) {
return false;
}
// allocate rows_lengths array
size_t rows_lengths_count = 4;
size_t *rows_lengths = malloc(rows_lengths_count * sizeof(size_t));
if (rows_lengths == NULL) {
free(tile_array);
tile_array = NULL;
return false;
}
char curr_char;
size_t curr_distance = 0;
size_t curr_row = 0;
size_t curr_col = 0;
struct tile *previous = NULL;
while ((curr_char = fgetc(file)) != EOF) {
assert(curr_distance <= array_length);
assert(curr_row <= rows_lengths_count);
// allocate more memory for tile_array
if (curr_distance == array_length) {
array_length += 4;
struct tile *tmp = realloc(tile_array, (array_length * sizeof(struct tile)));
if (tmp == NULL) {
free(tile_array);
tile_array = NULL;
free(rows_lengths);
rows_lengths = NULL;
return false;
}
tile_array = tmp;
tmp = NULL;
}
// allocate more memory for rows_lengths
if (rows_lengths_count == curr_row) {
rows_lengths_count += 4;
size_t *tmp = realloc(rows_lengths, (rows_lengths_count * sizeof(size_t)));
if (tmp == NULL) {
free(tile_array);
tile_array = NULL;
free(rows_lengths);
rows_lengths = NULL;
return false;
}
rows_lengths = tmp;
tmp = NULL;
}
if (curr_char == '\n') {
// set variables & continue
}
if (illegal_input_char(curr_char)) {
// invalid input, free memory & return false
}
// create new tile and insert to the maze
struct tile curr_tile = {false, curr_char, curr_distance, curr_row, curr_col, previous};
tile_array[curr_distance] = curr_tile;
printf("WRITTEN CHAR: '%lu', direction:%2lu", ((*maze).tile_array[curr_distance]).type, ((*maze).tile_array[curr_distance]).distance);
curr_col++;
curr_distance++;
previous = &curr_tile;
}
(*maze).length = curr_distance;
(*maze).row_count = curr_row - 1;
return true;
}
From what I see in the code, tile_array
and rows_lengths
are just local variables, and they are not the same as tile_array
and rows_lengths
members of the Maze.
However when you print them out, you refer to members of Maze, hence null output. You probably wanted to refer to (*maze).tile_array
and (*maze).rows_lengths
everywhere.