Как массив хранится в памяти? - PullRequest
5 голосов
/ 17 января 2011

Для того, чтобы глубже понять, как распределяется и хранится память, я написал приложение, которое может сканировать адресное пространство памяти, находить значение и записывать новое значение.

Я разработал пример приложения с конечной целью, чтобы иметь возможность программно найти мой массив и перезаписать его новой последовательностью чисел. В этой ситуации я создал одномерный массив из 5 элементов, например

int[] array = new int[] {8,7,6,5,4};

Я запустил свое приложение и искал последовательность из пяти чисел выше. Я искал любое значение, которое упало между 4 и 8, всего 5 чисел подряд. К сожалению, мои последовательные числа в массиве соответствовали сотням результатов, так как числа от 4 до 8 ни в какой конкретной последовательности не оказывались рядом друг с другом, в памяти, во многих ситуациях.

Есть ли способ отличить, что набор чисел в памяти представляет собой массив, а не просто целые числа, которые находятся рядом друг с другом? Есть ли способ узнать, что, если я найду определенное значение, что соответствующие ему значения соответствуют массиву?

Я бы предположил, что когда я объявляю int[] array, это указывает на первый адрес моего массива, который предоставит метаданные своего рода тому, что существовало в массиве, например

0x123456789 meta-data, 5 - 32 bit integers 
0x123456789 + 32 "8"
0x123456789 + 64 "7"
0x123456789 + 96 "6"
0x123456789 + 128 "5"
0x123456789 + 160 "4"

Я далеко от базы?

Ответы [ 5 ]

5 голосов
/ 17 января 2011

Отладка + Windows + Память + Память 1, установите в поле Адрес значение «массив».Вы увидите это, когда переключите представление на «4-байтовое целое число»:

0x018416BC  6feb2c84 00000005 00000008 00000007 00000006 00000005 00000004

Первый адрес - это адрес объекта в куче, собираемой мусором, плюс часть заголовка объекта,с отрицательным смещением (индекс syncblk).Вы не можете угадать это значение, GC перемещает его.2-е шестнадцатеричное число является «дескриптором типа» для типа массива (он же указатель таблицы методов).Вы не можете угадать это значение, дескрипторы типа создаются CLR по требованию.3-е число - длина массива.Остальные - значения элементов массива.

Вероятность надежного поиска этого массива во время выполнения без отладчика довольно мала.Нет особого смысла пытаться.

0 голосов
/ 17 января 2011

Хотя я вижу, что вы используете C # и, по-видимому, .NET, большая часть вашего вопроса в общих чертах касается памяти. Имейте в виду, что в самом общем смысле вся память - это просто биты, независимо от того, содержит ли она массив, строки или код.

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

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

0 голосов
/ 17 января 2011

Память не всегда сохраняется непрерывно.Если вы можете убедиться, что это так, то то, что вы просите, возможно.

0 голосов
/ 17 января 2011

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

0 голосов
/ 17 января 2011

Не.Массив хранится в куче и может быть перемещен из-за сбора мусора.Вы должны использовать fixed , если вам нужно убедиться, что память не перемещена, и вы можете использовать ее только очень осторожно.

Если вам нужны высокопроизводительные массивы, используйте stackalloc и используйте вашу кодовую схему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...