Nuno Carriço
Nuno Carriço

Reputation: 13

C - Seg. Fault in array of pointers

I am doing a school project in C and what I need to do is to create a 2D grid of agents where some of them are humans and the others are zombies. Humans run away from zombies and zombies try to infect them.

The game is turn-based and in every turn the movement order is random. In order to do that, I created an array of pointers that will hold all the agents so I can shuffle the array before every turn and with that, I get random agent movement order by cycling through the array of agents.

Problem is that when I'm creating that array of pointers I get segmentation fault and I can't understand why.The segmentation fault happens here:

agents_shuffle[c] = agent_new(type, playable, id, x, y);

Thanks for the help!

Here's the code in the main part of the program:

/* Array to save agent pointers for shuffle*/
AGENT **agents_shuffle = NULL;

AGENT_TYPE type = 0;
unsigned char playable = 0;
unsigned short id = 0;
int c = 0;

for (int x = 0; x < WORLD_X; x++) {
    for (int y = 0; y < WORLD_Y; y++) {
        if (agent_grid[x][y].type != None) {

            type = agent_grid[x][y].type;
            playable = agent_grid[x][y].playable;
            id = agent_grid[x][y].id;

            agents_shuffle[c] = agent_new(type, playable, id, x, y);
            c++;
        }
    }
}

Here's the agent.c file:

#include "agent.h"

AGENT *agent_new(AGENT_TYPE type, unsigned char playable, 
    short id, int x, int y) {

    AGENT *a = (AGENT *) malloc(sizeof(AGENT));
    a->type = type;
    a->playable = playable;
    a->id = id;
    a->x = x;
    a->y = y;

    return a;
}

void agent_destroy(AGENT *a) {
    free(a);
}

Struct agent:

/**
 * Structure defining agent properties.
 * */
typedef struct {
    AGENT_TYPE type;        /**< Agent type.              */
    unsigned char playable; /**< Is agent playable?       */
    unsigned short id;      /**< Agent ID.                */
    int x;                  /**< Agent position on x axis */
    int y;                  /**< Agent position on y axis */
} AGENT;

Here is agent grid defined:

/** Horizontal world size. */
#define WORLD_X 10

/** Vertical world size. */
#define WORLD_Y 10

/* A by-dimensional array of agents, representing agents in a grid. */
AGENT agent_grid[WORLD_X][WORLD_Y];

/* Number of agents created so far. */
unsigned int nagents = 0;

/* Initialize random number generator. */
srand(time(NULL));

/* **************************************************************** */
/* Cycle through all cells in grid and randomly place agents in it. */
/* **************************************************************** */
for (int i = 0; i < WORLD_X; ++i) {
    for (int j = 0; j < WORLD_Y; ++j) {

        /* Possible agent in grid. By default we assume there is none. */
        AGENT ag = {None, 0, 0, 0, 0};

        /* Obtain a probability between 0 and 99. */
        unsigned char probability = rand() % 100;

        /* There is 10% probability of creating an agent. */
        if (probability < 10) {

            /* If we got here, an agent will be placed at (i,j). */

            /* Randomly define agent type. */
            ag.type = (rand() % 2 == 0) ? Human : Zombie;

            /* Give 10% probablity of agent being playable by user. */
            ag.playable = (rand() % 10 == 0);

            /* Assign agent ID and then increment number of agents so
               far. */
            ag.id = nagents++;

            /* Agent Coordinates */
            ag.x = i;
            ag.y = j;

        }

        /* Assign possible agent to grid at (i,j). */
        agent_grid[i][j] = ag;

    }
}

Upvotes: 1

Views: 176

Answers (2)

Dixel
Dixel

Reputation: 564

You planned agent_shuffleto be an array of pointers.
But you initialized it as a pointer to a pointer
AGENT **agents_shuffle = NULL;
You need to change the previous line to
AGENT *agents_shuffle[WORLD_X*WORLD_Y];

Upvotes: 0

MFisherKDX
MFisherKDX

Reputation: 2866

You are de-referencing the NULL pointer agents_shuffle when you do agents_suffle[c].

Here, agents_shuffle is defined as an array of pointers to AGENT:

AGENT **agents_shuffle = NULL;

Your agent_new function allocates space for an agent and returns a pointer to it and attempts to store it into the array at agents_shuffle[c]. One problem that is likely causing a segfault is that space for this array is never allocated.

The max amount of space you need from your loop is WORLD_X*WORLD_Y elements in the array.

Try:

agents_shuffle = malloc((WORLD_X*WORLD_Y)*sizeof(*agents_shuffle));

Upvotes: 1

Related Questions