Обозначение кода динамической памяти

Bei char ** alloc_2d_char ( const int rows , const int cols ) { char * data = ( char *) malloc ( строки * cols * sizeof ( char )); char ** array = ( char **) malloc ( rows * sizeof ( char *)); для ( int i = 0 ; i < rows ; i ++) array [ i ] = & ( данные [ cols * i ]); return array ; } ga beginner Программист C / C ++, мне нужно потратить несколько часов, пытаясь расшифровать приведенный ниже код: Мог бы кто-нибудь пройти меня (пошаговый код ниже для динамического распределения памяти) по строкам.

char *data = (char *)malloc(rows*cols*sizeof(char));

Указатель на указатели объясняется отдельно, чем от указателей на rowss. Мне удалось получить часть информации из разных источников, но ни одна из них не строит линии сплоченно.

c,arrays,pointers,memory-management,

4

Ответов: cols


5 принят

Код использует единый непрерывный блок памяти для хранения двумерного sizeof (char).

char

Ok - эта строка выделяет пространство для всех 2-D строк * cols * sizeof (char). 2-D malloc - mallocchar по char *столбцам. Таким образом, общее количество элементов . Затем вам нужно умножить это на количество пространства, которое занимает каждый элемент, т. К. Это двумерные строки * sizeof (char *) of . Таким образом, общий объем выделяемой памяти является аргументом .char **array= (char **)malloc(rows*sizeof(char*));arraychar **for (int i=0; i<rows; i++) array[i] = &(data[cols*i]);array

rowsВызов возвращает указатель на выделенную память. Поскольку эта память будет использоваться для хранения cols, вы передаете возвращаемое значение . [0][1][2][3][4][5]

data[n]

nобъявляется как «указатель на указатель на 0», потому что это то, что он собирается делать. Он укажет на память, которая будет содержать указатели до 5. Это будет один указатель для каждой строки. Поэтому вам нужно выделить &data[n]память: количество указателей умножается на размер указателя правильного типа. А так как это было выделено для указания указателей на массив [ 0 ] = & data [ 0 ]; array [ 1 ] = & data [ 3 ]; , мы передаем возвращаемое значение . array[0]

[0]

Это волшебство :). Это устанавливает каждый указатель внутри, array[1]чтобы указать внутри блока фактического [3], выделенного ранее. Рассмотрим конкретный пример, где array[0][2]2 и array[0]равно 3. Тогда у вас есть блок из 6 символов в памяти:

array[0]

И [0][1][2](for nfrom 0to 5) является n-м элементом и [0]является [2] адресом n-го элемента.

Итак, что делает этот цикл в этом случае:

array[1][1]

Таким образом, array[1]указывает на начало субблока [3][4][5]и [3]указывает на начало субблока [4]. Затем, когда вы добавляете второй индекс, вы индексируете его с начала этого указателя. Таким образом, означает «получить указатель, который хранится внутри . Найдите то, на что он указывает, затем переместите вперед 2 элемента оттуда:char **alloc_2d_char(const int rows, const int cols) { // This allocates the chunk of memory that stores that actual data. // It is a one single-dimensional array that has rows*cols characters. char *data = (char *)malloc(rows*cols*sizeof(char)); // This allocates an array of pointers that will then be assigned to the // individual rows (carved out of the previous allocation). char **array= (char **)malloc(rows*sizeof(char*)); // This assigns each row to the appropriate position in the data array. // The &(data[cols*i]) bit of it is the address of a portion in the // memory pointed to by data. The cols*i is the offset to the portion that // represents row i. for (int i=0; i<rows; i++) array[i] = &(data[cols*i]); // After doing this, then you can assign a value such as: // array[r][c] = 'x'; // That statement would store 'x' into data[r*c + c] return array; }char *data = (char *)malloc(rows*cols*sizeof(char));

char **array= (char **)malloc(rows*sizeof(char*));указывает на (ну, на самом деле указывает ). Затем вы перемещаете два элемента вперед и получаете .array[i] = &(data[cols*i]);*int **

Или, если вы начинаете , указывает на (и на самом деле указывает на . Перемещайте один элемент вперед и получите .char **alloc_2d_char(const int rows, const int cols) { char *data = (char *)malloc(rows*cols*sizeof(char));chardatamalloc


1

Первые строки * cols * sizeof (char) получают память для массива 2D-символов. Вторые строки * cols получают память для индекса строк.

Цикл for устанавливает указатель на каждую строку.

Наконец, возвращается индекс строки.


1

Вы можете подумать о 2-D массиве, который он создает как массив одномерных массивов. Каждая запись строки указывает на массив символов, который представляет символ столбца для этой строки.

Ниже приведен исходный код с добавленными комментариями, чтобы попытаться описать каждый шаг:

malloc

1

Не сложно расшифровать ...

data

простое распределение памяти

rows*cols

выделение памяти указателей символа #row

(char *)

каждый массив [i] является указателем, указателем на malloc [cols * i]


1

Каждый *в объявлении ссылается на один уровень указателя. поэтому dataозначает указатель на указатель на int. Итак, ваша функция:

  char **array= (char **)malloc(rows*sizeof(char*));

возвращает указатель на указатель на символ.

array

Это объявляет указатель на char. Вызывается указатель char. Инициализация вызовов malloc, которая выделяет количество байтов, равное значению аргумента. Это означает, что есть rows*sizeof(char)байты, которые будут равны rows, так как a charравно 1 байт. Функция возвращает указатель на новую память , а это значит , что теперь указывает на кусок памяти , что это большой. Перед вызовом просто бросает новую память к тому же типу, что и указатель .arraydata for (int i=0; i<rows; i++) array[i] = &(data[cols*i]);arraymallocdata

data

arrayявляется указателем на указатель на a char. Он также назначается с использованием malloc. Объем памяти, выделяемой на этот раз , равен . Это означает, что это указатель на указатель на кусок памяти, достаточно большой, чтобы удерживать 1 строку.col: 0 1 2 3 ... cols-1 row: 0 * 1 * 2 * 3 * . . . rows-1 *rowsarray

array

Остальная часть вашего кода инициализирует каждый элемент arrayдля хранения адреса соответствующей строки большого фрагмента памяти. Ваш dataуказатель укажет на кусок памяти, который выглядит так:

   return array;
 }

И ваш arrayуказатель укажет на кусок памяти со списком указателей, каждый из которых указывает на одну из звездочек в куске памяти выше.

array

Это просто возвращает свой arrayуказатель на указатель, который соответствует типу возвращаемой alloc_2d_charфункции: char **. Это означает, что вызывающая функция по существу получит массив указателей, и каждый из этих указателей указывает на одну из строк двумерного массива.

с, массивы, указатели, управление памятью,
Похожие вопросы