У вас должно быть количество столбцов для каждой строки в массиве. Ваш код передает указатели на массивы требуемой длины, но вы не можете получить их длину от указателей.
Приведенный ниже код принимает число строк плюс массив с длиной каждого столбца. Он выделяет требуемый зубчатый массив, инициализируя его нулем с помощью вызова calloc
.
int** make_zeros_jagged_resizable(int rows, int* cols) {
// Allocate array for pointers.
int** result = malloc(sizeof(*result) * rows);
if (result == NULL) {
printf("allocation error\n");
return NULL;
}
// Allocate each of the rows and fill them with zeros.
for (int i = 0; i < rows; i++) {
result[i] = calloc(cols[i], sizeof(*result[i]));
if (result[i] == NULL) {
printf("allocation error\n");
// Free all the already-allocated rows.
for (int j = 0; j < i; j++) {
free(result[j]);
}
free(result);
return NULL;
}
}
return result;
}
Обратите внимание, что приведенный выше код требует много вызовов calloc
, что может быть медленным для большого количества строк. Кроме того, строки могут находиться далеко друг от друга в памяти. Если вы обычно просматриваете весь двумерный массив, может быть лучше выделить весь блок целых чисел за один вызов, а затем просто установить указатели, указывающие на этот единственный блок. Это имеет тот недостаток, что вы больше не можете изменять размеры отдельных строк. Смотрите код ниже.
int** make_zeros_jagged(int rows, int* cols) {
// Allocate array for pointers.
int** result = malloc(sizeof(*result) * rows);
if (result == NULL) {
printf("allocation error\n");
return NULL;
}
// Compute total number of ints.
size_t total_ints = 0;
for (int i = 0; i < rows; i++) {
total_ints += cols[i];
}
// Allocate array for ints, and zero it.
// This assumes that you do not want to resize the rows
// individually afterwards.
int* space = calloc(total_ints, sizeof(*space));
if (space == NULL) {
printf("allocation error\n");
free(result);
return NULL;
}
// Fill the pointer array with pointers to the correct
// parts of the int array.
size_t pos = 0;
for (int i = 0; i < rows; i++) {
result[i] = &space[pos];
pos += cols[i];
}
return result;
}