Использование недопустимых указателей/адресов памяти: C++ (Windows)

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

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

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

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

Спасибо.


person ChrisJH    schedule 25.03.2011    source источник
comment
Каким образом VC++ отказывается позволить вам сделать это? То есть, что вы пробовали до сих пор? Вы должны просто сказать void * x = (void *) 12345;   -  person Ernest Friedman-Hill    schedule 25.03.2011
comment
Если ваша цель — наблюдать за своими собственными переменными, почему вы пытаетесь получить доступ к памяти, которую не используете? Это не имеет никакого смысла.   -  person Daniel T.    schedule 25.03.2011
comment
Дэниел, я использую его, но, например, это может быть адрес в стеке или адрес удаленной кучи. Как я его использую - я не ожидаю, что он исчезнет, ​​но теоретически он может...   -  person ChrisJH    schedule 25.03.2011
comment
Эрнест, я придумаю упрощенный пример...   -  person ChrisJH    schedule 25.03.2011
comment
Эрнест. Интересно, что на упрощенном примере в новом проекте он работал нормально, но не в сочетании с большим сложным приложением - я думаю, более сложные распределения памяти происходят под поверхностью.   -  person ChrisJH    schedule 25.03.2011


Ответы (1)


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

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

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

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

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

person shoosh    schedule 25.03.2011
comment
Спасибо за это - я надеялся, что это будет немного менее бессмысленно, чем оказалось... Придется сделать это трудным путем... - person ChrisJH; 25.03.2011