Скажем, у меня есть int array: int arr[5][5]
и предполагается управление памятью на языке C.
Я хочу получить доступ к определенному элементу массива, используя только арифметику указателей и разыменование.
Предположим, я хотел получить доступ к элементу в: arr[i][j]
Сначала я попробовал сначала напечатать несколько вещей, чтобы понять, как работают адреса. Я напечатал адрес arr
, arr+1
и arr+2
, а arr+5
.
Это были результаты:
0x7fff58475b80
0x7fff58475b94
0x7fff58475ba8
0x7fff58475be4
Мне интересно, почему разница между каждым адресом составляет 14 (в шестнадцатеричном) или 20 (в десятичной системе).
Кроме того, когда вы создаете двухмерный массив в стеке, является указателем на массив указателей на блоки памяти, созданные? Вот как я предполагаю, что мы выделяем пространство для массива:
arr
на стек.arr
содержит адрес в исходное местоположение массива указателей.Это верно?
EDIT: Также предположим, что вы хотите получить доступ к arr [i] [j] посредством арифметики указателей. Как это будет сделано? Если массив распределен динамически, я думаю, вы можете сделать * (* (arr + i) +j). Я не уверен, как вы это делаете для статических распределений? Мое предположение - * (arr + ((row_size * (i)) +j)). Это верно?
Мне интересно, почему разница между каждым адресом составляет 14 (в шестнадцатеричном) или 20 (в десятичной системе).
Возможно, потому что в вашей системе размер int
равен 4
а во внутреннем массиве 5
int.
Чтобы получить представление о макете, попробуйте следующий код:
int a[5][5];
int k = 0;
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
a[i][j] = ++k;
int* p = &a[0][0];
for (int n = 0; n < 25; n++, p++)
printf("%d ", *p);
Выход
1 2 3 4 ... 25
В стандарте C++
есть примечание (в 8.3.4 Массивы [dcl.arrays]):
[Примечание. Из всего этого следует, что массивы в C++ сохраняются по строкам (последний индекс меняется быстрее), и первый индекс в объявлении помогает определить объем памяти, потребляемой массивом, но не играет никакой другой роли в индексе расчеты. -End note]
Array - это набор похожих элементов данных, хранящихся в смежной памяти.
int arr[5][5];
В этом объявлении будет выделено смежное расположение памяти для всех элементов. скажем, начальная память - 1000.
array starting array elements
address
arr[0]--> 1000 --> arr[0][0] arr[0][1] ... arr[0][4]
arr[1]--> 1020 --> arr[1][0] arr[1][1] ... arr[1][4]
arr[2]--> 1040 --> arr[2][0] arr[2][1] ... arr[2][4]
arr[3]--> 1060 --> arr[3][0] arr[3][1] ... arr[3][4]
arr[4]--> 1080 --> arr[4][0] arr[4][1] ... arr[4][4]
I'm wondering why the difference between each of address is 14(in Hexadecimal) or 20 (in decimal).
Каждый массив имеет 5 целых чисел, sizeof(int)
равен 4. Таким образом, для 5 целых чисел будет выделено 20 байт памяти. Из-за этого только вы получаете разницу между каждым адресом массива 20 байтов (в десятичном формате. В шестнадцатеричном виде это 14)
1. Allocate a pointer 'arr' on stack.
-No. Выделите указатель на указатель на целое число (arr
) в стеке. Это int **arr;
2. The arr pointer holds the address to the starting location of an array of pointers.
3. That array of pointers contains the starting location of a row in the 2-D array.
Теперь это правильно! Но это динамическое распределение памяти не статично!
Линейный адрес местоположения [i, j] в матрице 2d вычисляется по формуле:
linear_position = i * (capacity of column 0) + j;
Адрес рассчитывается из линейной позиции, используя размер массива и используя начальный адрес массива:
cell_address = &array[0][0] + linear_position * sizeof(array[0][0]);
Включение ваших значений в приведенные выше уравнения должно дать вам указание на различия в адресах.
capacity of column
Вы имели в виду емкость строки?
(1) Адрес памяти всех 5 * 5 элементов из arr [5] [5] is & arr [0] [0], & arr [0] [1]... & arr [0] [4], & arr [ 1] [0],... & arr [1] [4],... & arr [4] [4]. Все они расположены последовательно с разницей sizeof (int). В вашем os, sizeof (int) = 4.
(2) С точки зрения адреса, arr + 1 = & arr [1] [0], arr + 2 = & arr [2] [0]. Это просто другое представление. Первая форма указателя, более поздняя - форма массива.
arr
- это массив из 5 элементов типаint[5]
каждый.sizeof(int[5]) == 20
is a pointer to an array of pointers to memory blocks created?
Нет. Создан плоский массив «блоков памяти», каждый из которых, в свою очередь, является массивом. Возможно, это прояснит ситуацию:int arr[5][5]
совпадает сtypedef int Block[5]; Block arr[5];