0

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;
//     }
// }
10
  • Sorry i dont know if formatted in correctly as this is one of my first question ive asked, but i have put attached two images, 'expected output' and 'currrent output' which look like that are the same link but its not, there is two images
    – Alex
    Commented Apr 14, 2023 at 2:53
  • also ignore the printf statements, they were for debugging lol
    – Alex
    Commented Apr 14, 2023 at 2:55
  • 1
    The code you show should not build. What does malloc return? What is the variable w? Please try to create a minimal reproducible example, and edit your question to show it. Commented Apr 14, 2023 at 2:57
  • And the loop for (int i = 0; i < w->capacity; i++) is wrong for your "rock" allocation. You should be creating an array of height pointers. Then an array of width "rocks". The problem with your code is that you allocate to many pointers and "rocks". Commented Apr 14, 2023 at 3:00
  • 1
    @Someprogrammerdude Hii thanks i fixed it, turns out i mixed up row and columns in w->rocks[i][j]. When u mentioned my assert function for rock, i realised i had commented it out cus it kept failing, and i jus realised is because i mixed up the rows and collumns. Thanks for ur help.
    – Alex
    Commented Apr 14, 2023 at 3:40

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.