Hello i am currently writing a program to emulate bouldering in real life, where there is a Wall ADT where you can store certain rocks on the wall which is represented basically as a 2d matrix. Unfortunately, when i tried to implemement the adjacency matrix (struct rock **rocks) in the code below, some of the rocks wouldn't get added to the matrix. I don't know if its because my initailisation of the matrix in WallNew is not done correctly. But i initialised it by the w->capacity which is width times the height of the rockwall. I'm not sure what im doing wrong, if i can't fix it i might go to use a single pointer array instead, but I'm trying to implement this with no luck. My program takes in a list of data and then creates an matrix.
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "Wall.h"
struct wall {
int height;
int width;
int numRocks;
int capacity; // this is just here to simplify future operations
struct rock **rocks; // adjacency matrix storing rocks
// needs to be a double pointer
};
// struct rock is usually in wall.h but i moved it here so you could read it
struct rock {
int row;
int col;
Colour colour;
};
static int compareRocks(const void *ptr1, const void *ptr2);
/**
* Creates a new blank wall with the given dimensions
*/
Wall WallNew(int height, int width) {
assert(height > 0);
assert(width > 0);
Wall w = malloc(sizeof(*w));
if (w == NULL) {
fprintf(stderr, "error: out of memory\n");
exit(EXIT_FAILURE);
}
w->height = height;
w->width = width;
w->capacity = height * width;
// No rocks initially
w->numRocks = 0;
w->rocks = malloc(w->capacity * sizeof(struct rock*));
if (w->rocks == NULL) {
fprintf(stderr, "error: out of memory\n");
exit(EXIT_FAILURE);
}
for (int i = 0; i < w->capacity; i++) {
w->rocks[i] = calloc(w->capacity, sizeof(struct rock));
if (w->rocks[i] == NULL) {
fprintf(stderr, "error: out of memory\n");
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
w->rocks[i][j].row = -1;
w->rocks[i][j].col = -1;
// Default green
}
}
return w;
}
You can see below my programs output of the boulder wall compared to what it should be. The boulder wall stops adding rocks at a width greater than 20. (When inputed with a wall width of 25 and heigh of 20)expected output and current output You can see the difference where the rocks added just suddenly cuts off with not explanation. Even though i know the rocks are being processed because i added a printf statement to the rock add function which showed it worked. Ill put the rockadd fucntion below.
// Checks if rock is already present, true if rock exists
static int checkExistingRock(Wall w, struct rock g) {
return w->rocks[g.col][g.row].row != -1 && w->rocks[g.col][g.row].col != -1;
}
/**
* Adds a rock to the wall
* If there is already a rock at the given coordinates, replaces it
*/
void WallAddRock(Wall w, struct rock rock) {
// assert(validRock(w, rock));
assert(validRockColour(w, rock));
printf("wassup\n");
// if no existing rock numRocks++, otherwise replace rock
if (!checkExistingRock(w, rock)) {
printf("hello there\n");
w->numRocks++;
}
printf("come on\n");
printf("stuff: %d %d %d\n", rock.row, rock.col, rock.colour);
// set rock.col and rock.row to current rock
// This is redundant as place on w->rocks is the same pos,
// but for when it is handled singley this is useful
w->rocks[rock.col][rock.row].row = rock.row;
w->rocks[rock.col][rock.row].col = rock.col;
w->rocks[rock.col][rock.row].colour = rock.colour;
}
I tried different ways of implememnting the struct rocks array, like using single pointer array. However, i want to use a double pointer array in my implementation so even though i figured out single pointer im not sure what im doing for double pointers wrong.
Edit: I know that i should of looped by height andwidth the allocate memory for each row. But when i did that, my program showed these big memory errors. Below is the original code i did for it
// Loop run height times to allocate memory for each row of the rocks array
// for (int i = 0; i < height; i++) {
// w->rocks[i] = malloc(width * sizeof(struct rock));
// if (w->rocks[i] == NULL) {
// fprintf(stderr, "error: out of memory\n");
// exit(EXIT_FAILURE);
// }
// for (int j = 0; j < width; j++) {
// // initialise values in row
// w->rocks[i][j].row = -1;
// w->rocks[i][j].col = -1;
// // Default green
// w->rocks[i][j].colour = 0;
// }
// }