1

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;

    }
}
  • where is agent_grid defined? do you allocate memory for that? – Krzysztof Skowronek Jan 19 '18 at 23:15
  • you need to allocate memory for `agents_shuffle`. I don't see where that is happening in your code. What I see is that you've assigned it to NULL. – MFisherKDX Jan 19 '18 at 23:15
  • First of all you didn't specify where is `agent_grid` and how you allocate memory for it. Remember that 2D arrays you must first allocated memory for the outer array and then loop over the array and allocated memory for each cell to contain another array. You also did not specify where the seg fault occurs. – amine.ahd Jan 19 '18 at 23:19
  • You will want to review: [Is it a good idea to **typedef** pointers?](http://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers) and [**Do I cast the result of malloc?**](http://stackoverflow.com/q/605845/995714). – David C. Rankin Jan 19 '18 at 23:30

2 Answers2

1

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));
MFisherKDX
  • 2,840
  • 3
  • 14
  • 25
0

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];

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
Dixel
  • 516
  • 1
  • 4
  • 9