Кто может показать пример функции, которая выделит память под двумерный массив и вернет его если это вообще возможно. И какие параметры нужно передать в эту функцию что бы достичь желаемого результата. Массив в итоге будет заполнен отдельными словами.
Ответ
Казалось бы, что может быть прямолинейнее, чем выделение динамически памяти под двумерный массив, а потому должно существовать одно решение.
На самом деле можно по-разному реализовать данную задачу.
Самый простой способ - это когда число колонок в двумерном массиве является константным значением, определенным либо с помощью директивы #define либо с помощью перечислителя. Тогда можно сразу же разместить динамически именно двумерный массив.
Второй подход, это когда число колонок задается во время выполнения программы. В этом случае обычно выделяют несколько одномерных массивов. Сначала выделяют одномерный массив указателей с количеством элементов равных количеству строк в предполагаемом двумерном массиве, А затем для каждого указателя этого одномерного массива выделяют массив объектов базового типа, число элементов которого равно числу колонок в двумерном массиве. В этом варианте важно учитывать, что во время выделения массивов может возникнуть нехватка памяти, а потому желательно правильно удалить те массивы, которые были уже распределены, а иначе программа будет иметь неопределенное состояние.
Третий подход заключается в использовании массивов переменной длины при условии, что C компилятор их поддерживает. Тогда число колонок и строк может быть задано во время выполнения программы, и можно выделить сразу же двумерный массив, а не массив массивов, как было описано в предыдущем абзаце.
Также следует не забывать корректно освобождать выделенную динамически память под массивы, когда массивы уже не нужны.
Ниже приведена демонстрационная программа, в которой показаны перечисленные способы выделения памяти для работы с двумерными массивами или их аналогами.
#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
Комментариев нет:
Отправить комментарий