Как освободить указатель на массив целых чисел - PullRequest
0 голосов
/ 25 апреля 2018

У меня проблемы с выяснением, как освободить указатель на массив целых чисел, мой код выглядит следующим образом:

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));
}

Я объявляю указатель в первой строке, инициализирую его во второй и устанавливаю все значения в 0 внутри for. Работает нормально.

После того, как я загружу новые значения и использую их, я хочу освободить указатель. Я делаю следующее:

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

Я пытаюсь сначала освободить массивы, а затем освободить указатель. Я получаю «сработала точка останова» при первом запуске «free (gameInfo [i])».

Я читал, что массив, поскольку он не имеет динамически распределенной памяти, не должен быть свободным, но если я удаляю for и просто оставляю free(gameInfo);, он выдает ту же ошибку. Я где-то читал это в блоге, поэтому не уверен, что это заслуживает доверия.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 25 апреля 2018

Для начала вы выделяете неправильно. Вы используете указатель массива, поэтому он должен указывать на массив, а не на какую-то фрагментированную таблицу поиска указателей.

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

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

free(gameInfo);

Вот и все.

Это не только сделало код более читабельным, но и значительно улучшило производительность.

Дальнейшее изучение: Правильное размещение многомерных массивов .

0 голосов
/ 25 апреля 2018
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);

После некоторых тестов я обновил его. Причина кроется в невыравнивании memset и malloc. Очевидно, вы применили 2 * sizeof (int) памяти и memset 2 раза по 2 * sizeof (int), что выходит за пределы диапазона 8 байт, который вы применили. Применить 16 байт, в моей системе исправлена ​​проблема. И спасибо, что @Lundin напомнил мне о проблеме.

0 голосов
/ 25 апреля 2018

Во-первых, для ваших заявленных целей, декларация:

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

Может быть:

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

Тогда распределение для обоих элементов массива будет выглядеть так:

int size = 10; // for example

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

Это, по сути, создает количество пространства , эквивалентное тому, которое вы имели бы с двумерным массивом int, например:

int gameInfo[2][10];

После использования освободите их:

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

Лучшим вариантом , как упоминалось в комментариях, может быть создание структуры:

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

Использование может включать создание, использование и освобождение массива игр:

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);
...