Выделение памяти для двухмерного массива произвольной длины

Последнее обновление: 11.01.2023

Рассмотрим работу с функциями выделения и освобождения памяти на примере более сложной задачи - динамическое выделение памяти для двухмерного зубчатого массива произвольной длины:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	int **table;	// указатель для блока памяти для массива указателей
	int *rows;		// указатель для блока памяти для хранения информации по строкам

	int rowscount;	// количество строк
	int d;		// вводимое число
	
	// ввод количества строк
	printf("Rows count=");
	scanf("%d", &rowscount);

	// выделяем память для двухмерного массива
	table = calloc(rowscount, sizeof(int*));
	rows = malloc(sizeof(int)*rowscount);
	// цикл по строкам
	for (int i = 0; i<rowscount; i++)
	{
		printf("\nColumns count for row %d=", i);
		scanf("%d", &rows[i]);
		table[i] = calloc(rows[i], sizeof(int));

		for (int j = 0; j<rows[i]; j++)
		{
			printf("table[%d][%d]=", i, j);
			scanf("%d", &d);
			table[i][j] = d;
		}
	}
	printf("\n");

	// вывод введенных чисел на консоль
	for (int i = 0; i<rowscount; i++)
	{
		printf("\n");

		for (int j = 0; j<rows[i]; j++)
		{
			printf("%d \t", table[i][j]);
		}
		// освобождение памяти для одной строки
		free(table[i]);
	}
	
	// освобождение памяти
	free(table);
	free(rows);

	return 0;
}

Переменная table представляет указатель на массив указателей типа int*. Каждый указатель table[i] в этом массиве представляет указатель на подмассив элементов типа int, то есть отдельные строки таблицы. А переменная table фактически представляет указатель на массив указателей на строки таблицы.

Но в данном случае мы будем определять память не просто для двухмерного массива, а для зубчатого массива, где разные строки, могут иметь разное количество столбцов. И д ля хранения количества элементов в каждом подмассиве определяется указатель rows типа int. Фактически он хранит количество столбцов для каждой строки таблицы.

Сначала вводится количество строк в переменную rowscount. Количество строк - это количество указателей в массиве, на который указывает указатель table. И кроме того, количество строк - это количество элементов в динамическом массиве, на который указывает указатель rows. Поэтому вначале необходимо для всех этих массивов выделить память:

table = calloc(rowscount, sizeof(int*));
rows = malloc(sizeof(int)*rowscount);

Далее в цикле осуществляется ввод количества столбцов для каждый строки. Введенное значение попадает в массив rows. И в соответствии с введенным значением для каждой строки выделяется необходимый размер памяти:

scanf("%d", &rows[i]);
table[i] = calloc(rows[i], sizeof(int));

Затем производится ввод элементов для каждой строки.

В конце работы программы при выводе происходит освобождение памяти. В программе память выделяется для строк таблицы, поэтому эту память надо освободить:

free(table[i]);

И кроме того, освобождается память, выделенная для указателей table и rows:

free(table);
free(rows);

Консольный вывод программы:

Rows count=2

Columns count for 1=3
table[0][0]=1
table[0][1]=2
table[0][2]=3

Columns count for 2=2
table[1][0]=4
table[1][1]=5

1	2	3
4	5
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850