Рассмотрим работу с функциями выделения и освобождения памяти на примере более сложной задачи - динамическое выделение памяти для двухмерного зубчатого массива произвольной длины:
#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