Bruno Teixeira
Bruno Teixeira

Reputation: 103

How to free pointer to an array of integers

I'm having problems figuring out how to free a pointer to an array of integers, my code is as follow:

int (*gameInfo)[2]; // [0] # of fouls || [1] # of players
gameInfo = (int *)malloc(size * sizeof(int*));
for (int i = 0; i < size; i++) {
    memset(gameInfo[i], 0, 2 * sizeof(int));
}

I declare the pointer in the first line, initialize it in the second, and sets all values to 0 inside the for. It works fine.

After I load the new values, and use them I want to free the pointer. I do the following:

for (int i = 0; i < size; i++) {
    free(gameInfo[i]);
}
free(gameInfo);

I'm trying to free the arrays first, and then free the pointer. I get a "has triggered a breakpoint" the first time it tries to execute "free(gameInfo[i])".

I've read that the array, since it doesn't have dynamic allocated memory, doesn't need to be free, but if I remove the for and just leave free(gameInfo); it gives the same error. I've read this in a blog somewhere, so I'm not sure if it's trustworthy.

Thank you!

Upvotes: 1

Views: 2032

Answers (3)

Shore
Shore

Reputation: 1023

int(*gameInfo)[2];
gameInfo = (int*)malloc(4 * sizeof(int*));
for (int i = 0; i < 2; i++) {
    memset(gameInfo[i], 0, 2 * sizeof(int));
}
free(gameInfo);

After some tests, I updated it. The reason lies on nonalignment of memset and malloc. Obviously you applied 2*sizeof(int) memory and memset 2 times of 2*sizeof(int), which is out of the range of 8 byte you applied. Apply 16 byte, in my system fixed the problem. And thanks for @Lundin for reminding me the problem.

Upvotes: 0

ryyker
ryyker

Reputation: 23218

First, for your stated purposes, the declaration:

int (*gameInfo)[2]; // [0] # of fouls || [1] # of players

Could be:

int *gameInfo[2]; // [0] # of fouls || [1] # of players

Then, allocation for both elements of the array would look like this:

int size = 10; // for example

gameInfo[0] = malloc(size * sizeof(*gameInfo[0]));
gameInfo[1] = malloc(size * sizeof(*gameInfo[1]));

This essentially creates a quantity of space equivalent to that you would have with a 2D int array such as:

int gameInfo[2][10];

After use, free them:

free(gameInfo[0]);
free(gameInfo[1]);

A better option, as mentioned in the comments might be to create a struct:

typedef struct {
   int fouls;
   int players;
} GAME;

Usage can then include creating, using then freeing an array of games:

GAME *game;
game = calloc(10, sizeof(*game));
...
game[0].fouls = 3;
game[0].players = 2;
...
game[9].fouls = 6;
game[9].players = 3;
...
free(game);

Upvotes: 2

Lundin
Lundin

Reputation: 213862

To begin with, you allocate incorrectly. You are using an array pointer, so it should be set to point at an array, not to some fragmented pointer look-up table.

int (*gameInfo)[players]; // [0] # of fouls || [1] # of players
gameInfo = calloc(1, sizeof( int[fouls][players] ));

...
gameInfo[x][y] = something;
...

free(gameInfo);

That's it.

Not only did this turn the code much more readable, it also improves performance drastically.

Further study: Correctly allocating multi-dimensional arrays.

Upvotes: 0

Related Questions