Карта памяти для 2D-массива в C

Считаете ли вы, что такое обсуждение карты памяти 2D-массива верно? Особенно эта фотография? Можете ли вы объяснить теорию?

Предположим, что мы объявляем 2D-массив в C следующим образом:

int arr[3][3]={10, 20, 30, 40, 50, 60, 70, 80, 90}; 

Теперь, согласно этому обсуждению, память будет организована следующим образом:

введите описание изображения здесь

Теперь я написал следующий код для проверки этой теории:

 #include  main() { int arr[3][3]={10, 20, 30, 40, 50, 60, 70, 80, 90}; printf(" arr==%d\n", arr); printf(" &arr[0]==%d\n", &arr[0]); printf(" arr[0]==%d\n", arr[0]); printf("&arr[0][0]=%d\n", &arr[0][0]); printf(" arr[0][0]=%d\n", arr[0][0]); } /* Output: ======== arr ==1245028 &arr[0] ==1245028 arr[0] ==1245028 &arr[0][0]==1245028 arr[0][0]==10 Press any key to continue... */ 

Почему первые 4 выхода одинаковы?

Ваш код просто использует простой multidimensional array, но изображение описывает массив указателей, например, тот, который вы обычно делаете, когда делаете malloc-ing.

Многомерный массив – это просто обычный, сплющенный массив (в памяти) с некоторым дополнительным синтаксическим сахаром для доступа. Поэтому, хотя можно получить указатель от arr [i], нет никакой дополнительной «переменной», просто чтобы сохранить это, как это происходит на вашем изображении.

Чтобы исправить изображение, удалите части с помощью arr[0], arr[1]... и измените значение arr на 1245039 (то же, что и arr [0] [0]).

См. Мой вопрос здесь.

Это не так, как вы получаете доступ к информации о 2-х массивах. Фактически, вы можете просто думать о них как о 1-й, где вы умножаете и добавляете индексы особым образом.

например

 int x[10] = {0,1,2,3,4,5,6,7,8,9}; int y[2][5] = {{0,1,2,3,4},{5,6,7,8,9}}; 

Они отформатированы точно так же в памяти, и они выглядят так:

 |0|1|2|3|4|5|6|7|8|9| 

Таким образом, чтобы получить элемент 8 , вы можете либо запросить x[8] , либо y[1][3] .

Во-вторых, вы можете думать о нем как (1 * 5) + 3 .

Вот почему ваши первые 4 были одинаковыми. У тебя есть:

  • arr : это адрес начала массива
  • arr[0] : это адрес начала первого подmatrix, который совпадает с началом всего массива
  • &arr[0][0] : это адрес первого элемента первого вспомогательного массива, а также начало всего массива
  • arr[0][0] : это значение, сохраненное в первом элементе первого подmatrix.

Первые четыре выхода одинаковы, почему нужно получить адрес первого элемента в массиве, т. Е. & Arr [0] [0]. Последним выходом является его содержимое.

ну, насколько я помню, в C ++ (и я думаю, что C, хотя это не моя сильная сторона) 2d-массив, объявленный как Values[][] , обычно (не знаю, всегда) реализован как массив C-стиля массивы. однако, когда вы объявляете их в стеке (например, локальная переменная), я считаю, что форматирование памяти отличается.

поэтому, когда вы объявляете локальную переменную, все выкладывается так, как будто это всего лишь 1d-массив, и вы получаете все, что вы можете наложить на указатель, а затем получить доступ как массив 1D. (!) однако, это все же распознается так же, как обычный 2D-массив в пределах области объявления, и, возможно, если вы перейдете к параметру, который объявлен с помощью [] нотации.

но, если вы выделяете одну из них в кучу (например, глобальную или статическую или через новую), история отличается. теперь память выставляется как фактический массив массивов, и поэтому фактические результаты местоположений памяти, которые вы индексируете, если вы отбрасываете 1D-массив и индекс, теперь будут указателями.

Я подтвердил свой отзыв, выполнив следующие действия: i создал int HeapArray[3][3]; как глобальный, и int StackArray[3][3]; (как с инициализаторами { { 10, 20, 30 }, {40, 50, 60}, {70, 80, 90 } } ). внутри моей функции я отбрасываю оба из них в указатель int* ptrHeapArray = (int*)HeapArray; , int* ptrHeapArray = (int*)HeapArray; и int* ptrStackArray = (int*)StackArray; а затем посмотрел на возвращаемое значение 0-го элемента каждого из них.

[edit: whoops, я их отменил; теперь исправлено]

ptrStackArray[0] был равен 10

ptrHeapArray[0] был равен указателю на int [3];

поэтому я думаю, что мой ограниченный отзыв является точным. 🙂 надеюсь это поможет!

  • 2D-массивы с использованием NSMutableArray
  • Использование Linq с 2D-массивом, Select not found
  • Синтаксис для создания двумерного массива
  • Передача 2D-массива в другую активность
  • Класс Java Comparator для сортировки массивов
  • Отправка и получение 2D-массива по MPI
  • Является ли 2d-массив двойным указателем?
  • Давайте будем гением компьютера.