Существуют различные способы выделения матрицы 2D int
:
Вы можете выделить массив массивов int
.
Вы можете выделить массив указателей для массивов int
и выделить отдельный массив int
для каждого из этих указателей.Это то, что вы пробовали, но размеры выделения неверны.
Массив указателей на массивы int
должен иметь размер cats * sizeof(int *)
.и каждый массив int
должен быть размещен во внешнем цикле размером loops * sizeof(int)
, а не во внутреннем цикле, который вы сделали.
Кроме того, вы должны освободить эти объекты перед выходом из программы, чтобыValgrind может видеть чистую пластину.
Вот исправленная версия:
#include <stdio.h>
#include <stdlib.h>
#define cats 3
#define loops 30
int main() {
int **a;
int i, j;
a = malloc(cats * sizeof(int *));
for (i = 0; i < cats; i++) {
a[i] = malloc(loops * sizeof(int));
for (j = 0; j < loops; j++) {
a[i][j] = i + j;
}
}
for (i = 0; i < cats; i++) {
for (j = 0; j < loops; j++)
printf("%d ", a[i][j]);
printf("\n");
}
for (i = 0; i < cats; i++)
free(a[i]);
free(a);
return 0;
}
Этот стиль косвенной 2D матрицы обычно вызывает недовольство, потому что:
- его сложнее и медленнее распределять, особенно если вы хотите избежать утечек памяти при частичном сбое выделения, что здесь не делается.
- обычно он менее эффективен для доступа, поскольку компиляторгенерирует 2 чтения из памяти для чтения значения вместо потенциального умножения и одного чтения.
- его сложнее освободить.
Есть некоторые преимущества, ни одно из которых не требуетсяздесь:
- можно не выделять несколько строк
- можно делить одинаковые строки (за счет усложнения dealloca))
- строки могут иметь разные размеры, но это больше не матрица
- строки могут быть эффективно заменены.
Другой подход, который считаетсятолько действительная 2D матрица , использует одиночное распределение и несколько менее очевидный тип для указателя матрицы:
int (*a)[loops] = malloc(sizeof(int) * loops * cats);
, который можно записать:
int (*a)[loops] = malloc(sizeof(*a) * cats);
иливозможно более читабельно:
int (*a)[loops] = malloc(sizeof(int[cats][loops]));
a
указывает на массив cats
массивов loops
int
.
Этот подход был возможен только в ранних версиях C, еслиloops
было константным выражением, как и в вашей программе, но это ограничение было снято в C99.
Вот упрощенная версия вашей программы с таким подходом:
#include <stdio.h>
#include <stdlib.h>
#define cats 3
#define loops 30
int main() {
int (*a)[loops] = malloc(sizeof(*a) * loops);
if (a != NULL) {
for (i = 0; i < cats; i++) {
for (j = 0; j < loops; j++)
a[i][j] = i + j;
}
for (i = 0; i < cats; i++) {
for (j = 0; j < loops; j++)
printf("%d ", a[i][j]);
printf("\n");
}
free(a);
}
return 0;
}