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;
// }
// }
malloc
return? What is the variablew
? Please try to create a minimal reproducible example, and edit your question to show it.for (int i = 0; i < w->capacity; i++)
is wrong for your "rock" allocation. You should be creating an array ofheight
pointers. Then an array ofwidth
"rocks". The problem with your code is that you allocate to many pointers and "rocks".