Страницы

Поиск по вопросам

суббота, 15 июня 2019 г.

Выделение памяти под двумерный массив malloc

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


Ответ

Казалось бы, что может быть прямолинейнее, чем выделение динамически памяти под двумерный массив, а потому должно существовать одно решение.
На самом деле можно по-разному реализовать данную задачу.
Самый простой способ - это когда число колонок в двумерном массиве является константным значением, определенным либо с помощью директивы #define либо с помощью перечислителя. Тогда можно сразу же разместить динамически именно двумерный массив.
Второй подход, это когда число колонок задается во время выполнения программы. В этом случае обычно выделяют несколько одномерных массивов. Сначала выделяют одномерный массив указателей с количеством элементов равных количеству строк в предполагаемом двумерном массиве, А затем для каждого указателя этого одномерного массива выделяют массив объектов базового типа, число элементов которого равно числу колонок в двумерном массиве. В этом варианте важно учитывать, что во время выделения массивов может возникнуть нехватка памяти, а потому желательно правильно удалить те массивы, которые были уже распределены, а иначе программа будет иметь неопределенное состояние.
Третий подход заключается в использовании массивов переменной длины при условии, что C компилятор их поддерживает. Тогда число колонок и строк может быть задано во время выполнения программы, и можно выделить сразу же двумерный массив, а не массив массивов, как было описано в предыдущем абзаце.
Также следует не забывать корректно освобождать выделенную динамически память под массивы, когда массивы уже не нужны.
Ниже приведена демонстрационная программа, в которой показаны перечисленные способы выделения памяти для работы с двумерными массивами или их аналогами.
#include #include #include
#define COLS 10
char ( * first_allocate( size_t rows ) )[COLS] { char ( *s )[COLS] = malloc( rows * sizeof( char[COLS] ) );
return s; }
void first_free( char ( *s )[COLS] ) { free( s ); }
char ** second_allocate( size_t rows, size_t cols ) { char **s = malloc( rows * sizeof( char * ) );
if ( s != NULL ) { size_t i = 0;
while ( i < rows && ( s[i] = malloc( cols * sizeof( char ) ) ) != NULL ) i++;
if ( i != rows ) { for ( size_t j = i; j != 0; j-- ) free( s[j-1] ); free( s ); s = NULL; }
}
return s; }
void second_free( char **s, size_t rows ) { for ( size_t i = 0; i < rows; i++ ) free( s[i] ); free( s ); }
void third_allocate( size_t rows, size_t cols, char ( **s )[rows][cols] ) { *s = malloc( sizeof( char[rows][cols] ) ); }
void third_free( size_t rows, size_t cols, char ( *s )[rows][cols] ) { free( s ); }

int main( void ) { size_t rows = 2; size_t cols = 10;
char ( *s1 )[COLS] = first_allocate( rows ); strcpy( s1[0], "first" ); strcpy( s1[1], "second" );
for ( size_t i = 0; i < rows; i++ ) printf( "%s ", s1[i] ); printf( "
" );
first_free( s1 );
printf( "
" );
char **s2 = second_allocate( rows, cols ); strcpy( s2[0], "first" ); strcpy( s2[1], "second" );
for ( size_t i = 0; i < rows; i++ ) printf( "%s ", s2[i] ); printf( "
" );
second_free( s2, rows );
printf( "
" );
char ( *s3 )[rows][cols] = NULL;
third_allocate( rows, cols, &s3 ); strcpy( ( *s3 )[0], "first" ); strcpy( ( *s3 )[1], "second" );
for ( size_t i = 0; i < rows; i++ ) printf( "%s ", ( *s3 )[i] ); printf( "
" );
third_free( rows, cols, s3 ); }
Вывод программы на консоль будет следующим
first second
first second
first second

Комментариев нет:

Отправить комментарий