Initializing an array of pointers to structs using double pointer

51 Views Asked by At

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;
//     }
// }
0

There are 0 best solutions below