Использование неверных указателей / адресов памяти: C ++ (windows) - PullRequest
1 голос
/ 25 марта 2011

Я пытаюсь написать переменный класс мониторинга, который позволяет мне передавать ему указатель (в идеале void *), обращающийся к области памяти, которая обычно была бы полностью вне области или недоступна для класса. Затем класс будет периодически отображать на экране в тексте содержимое этой ячейки памяти - интерпретировать определенным пользователем способом (например, (int *)). Я только когда-либо читал бы из памяти, используя этот указатель, и это послужило бы грязным хаком для включения своего рода окна наблюдения во время разработки для переменных, которые я временно заинтересован в мониторинге во время выполнения - без введения большого количества кода эти переменные в области видимости / доступны для класса.

Я использую VC ++ 2010, и кажется, что он отказывается разрешить мне даже написать адрес памяти вне области видимости для указателя.

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

Есть идеи, как я могу это сделать? (Я понимаю, что использование таких указателей приводит к неопределенному поведению, поэтому будет только читать из них и отображать значение).

Спасибо.

1 Ответ

1 голос
/ 25 марта 2011

Попытка разыменования указателей, указывающих вне любого пространства, которое вы можете объяснить, в значительной степени бессмысленна.Возможно, адрес, к которому вы обращаетесь, может даже не отображаться в области памяти вашего процесса, поэтому на самом деле вам даже нечего смотреть.
Когда ваш процесс запускается, у вас фактически нет 4 ГБ в вашем распоряжении.объем памяти составляет 4 ГБ, но в основном он состоит из дыр, которые не отображаются в вашем процессе.

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

  • выделений кучи - все, что находится внутри диапазонов, выделенных malloc или new, и еще не free dили deleted
  • пространство стека, глобальные переменные - все, что вы определяете как переменные в вашей программе в пределах вашей текущей позиции в программе.Доступ к чему-либо определенному в других областях не имеет смысла (например, возвращая указатель на локальную переменную из функции)
  • сегменты кода - адреса внутри сегментов памяти, которые содержат DLL или EXE вашего процесса, которые не быливыгружен.Обычно вы можете получить к ним доступ только для чтения.Вы можете найти такие адреса, например, посмотрев адрес возврата функции.

Доступ к указателю в только что освобожденном фрагменте памяти - это как раз тот случай такой бессмысленности.После того, как вы освободили свою память, есть определенный шанс, что она уже была возвращена в ОС и этот адрес больше не отображается в вашем процессе.

Подробнее об этом можно прочитать здесь

...