Страницы

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

суббота, 11 января 2020 г.

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

#c #массивы #указатели #malloc


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


Ответы

Ответ 1



Казалось бы, что может быть прямолинейнее, чем выделение динамически памяти под двумерный массив, а потому должно существовать одно решение. На самом деле можно по-разному реализовать данную задачу. Самый простой способ - это когда число колонок в двумерном массиве является константным значением, определенным либо с помощью директивы #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( "\n" ); first_free( s1 ); printf( "\n" ); 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( "\n" ); second_free( s2, rows ); printf( "\n" ); 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( "\n" ); third_free( rows, cols, s3 ); } Вывод программы на консоль будет следующим first second first second first second

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

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