Reputation: 103
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
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
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
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