Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как достать доступ к виртуальной памяти


Автор: GIK 6.2.2007, 22:58
Народ, привет smile
Вобщем прочитал я пару статей про виндовую адресацию памяти, теперь интересует следующее:
Компилятор не дает значение данных хранимых, к примеру, в виртуальной области от 0x00000000 до 0x0000FFFF Если я создаю указатель, то он ссылается на первый байт, но значение от этого указателя нельзя получить и присвоить соответсятвенно тоже.
Как можно сделать так, чтобы доступ открылся?

Код

#include<conio>
#include<iostream>
using namespace std;

int main()
{
    void *g;
    int p=123;
    cout<<g<<endl; //результат- 1-ый бай ВИРТУАЛЬНОГО адресного пространства
    //cout<<*g<<endl; //и к нему нет доступа!!! (прочесть нельзя)
    //int ooo=*g;

    int *g2;
    int p2=123;
    g2=&p2;
    cout<<g2<<endl;  //адреса для кода и данных пользовательского режима, начинаются 
                                 //с 0x00010000 и заканчиваются 0x7FFEFFFF
    cout<<*g2<<endl;



    getche();
        return 0;
}


Добавлено @ 23:12 
Да, еще, чуть не забыл smile


Код

#include<conio>
#include<iostream>
using namespace std;

int main()
{
  
    int *g2;
    int p2=123;
    g2=&p2;
    g2++; //странно даже......
    cout<<g2<<endl;  //а что выдает то....
    cout<<*g2<<endl;
    getche();
        return 0;
}

Очень интересно наблюдать, когда выкидывает одинаковые числа smile

Код

#include<conio>
#include<iostream>
using namespace std;

int main()
{
  
    int *g2;
    int p2=123;
    g2=&p2;
    cout<<g2<<endl;  
    cout<<*g2<<endl;
    getche();
        return 0;
}


Автор: Anikmar 6.2.2007, 23:17
По поводу первого участка:
Код

    void *g;
    int p=123;
    cout<<g<<endl; //результат- 1-ый бай ВИРТУАЛЬНОГО адресного пространства
    //cout<<*g<<endl; //и к нему нет доступа!!! (прочесть нельзя)


А почему вы решили, что значение указателя g должно указывать на 1-й байт виртуальной памяти? Откуда такие утверждения? Вы просто видите значение переменной типа "указатель", которая НИЧЕМ не проинициализирована...

Автор: GIK 6.2.2007, 23:37
Куда указывает указатель? Не на память с адресом в один байт?

Автор: Anikmar 6.2.2007, 23:42
Он никуда не указывает! Это просто указатель. Чтобы он на что-то указывал ему нужно присвоить какое-нибудь значение. А так - все зависит от компилятора. В билдере, насколько я помню, указатель инициализируется значениме чуть больше нуля. Но не факт и в стандарте не прописано (насколько я знаю).

Автор: Romikgy 6.2.2007, 23:42
Код

long * x;

Автор: Anikmar 6.2.2007, 23:43
Romikgy, и? 
Не врубился...

Автор: Romikgy 6.2.2007, 23:47
Цитата(GIK @  6.2.2007,  22:37 Найти цитируемый пост)
Куда указывает указатель? Не на память с адресом в один байт?


Цитата(Romikgy @  6.2.2007,  22:42 Найти цитируемый пост)
    
long * x;

я привел пример где указатель указывает на 4 бафта smile

Автор: Anikmar 6.2.2007, 23:53
Цитата(Romikgy @  6.2.2007,  23:47 Найти цитируемый пост)
я привел пример где указатель указывает на 4 бафта  

И опять неправильно. С чего это следует? Пока он не инициализирован он никуда не указывает. Он МОЖЕТ указывать на память из 4-х байт (вернее на long).
А если взять конструкцию:
Код

long *pLong;
char *pChar;
long i;

pLong = &i;
pChar = (char*)pLong;


pLong и pChar имеют одно и тоже значение? И на какой участок памяти они указывают?

Автор: Romikgy 7.2.2007, 00:03
да неправильно высказался
Цитата(Anikmar @  6.2.2007,  22:53 Найти цитируемый пост)
указатель

Цитата(Anikmar @  6.2.2007,  22:53 Найти цитируемый пост)
на 4 байта

так правильно?

Автор: GIK 7.2.2007, 00:12
Мне кажется в любом случае, если есть значение у указателя, значет оно, хотябы косвенно, куда то указывает.... Разве я не прав?
Почему тогда нельзя взять данные из области с адресом 1? Или вообще нельзя брать данные, из неинициализированного указаьеля?

Автор: Romikgy 7.2.2007, 00:18
Цитата(GIK @  6.2.2007,  23:12 Найти цитируемый пост)
Или вообще нельзя брать данные, из неинициализированного указаьеля? 

смотря что в нем 
Цитата(GIK @  6.2.2007,  23:12 Найти цитируемый пост)
Почему тогда нельзя взять данные из области с адресом 1?

срабатывает имхо защита на доступ в системную область

Автор: Anikmar 7.2.2007, 00:20
Цитата(GIK @  7.2.2007,  00:12 Найти цитируемый пост)
Мне кажется в любом случае, если есть значение у указателя, значет оно, хотябы косвенно, куда то указывает.... Разве я не прав?

Нет, это не так. Поцессу выделено его адрессное пространство, но память разделена на блоки. И каждый блок должен быть выделен менеджером памяти. Если указателю присвоить произвольное значение, то это далеко не всегда попадает в распределенное пространоство для процесса. В MSDOS так можно было - пробежаться по выделенным блокам, да и в любое место залесть было можно. Но стандартом Си++ это уже никак не определено - память должна выделяться в нужном объеме и освобождаться после. Произвольные адреса не допускаются.

Автор: vinter 7.2.2007, 00:24
Цитата

Или вообще нельзя брать данные, из неинициализированного указаьеля?

нельзя, и нормальный компилятор будет на это ругаться..

Автор: Anikmar 7.2.2007, 00:35
Цитата(vinter @  7.2.2007,  00:24 Найти цитируемый пост)
нельзя, и нормальный компилятор будет на это ругаться.. 

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

Я думал, что все что он скажет - это предупреждение "Возможное использование переменной до ее инициализации".  (зачастую оно по умолчанию выключено)

Или я чего-то не знаю?

Автор: SergeCpp 7.2.2007, 10:20
Цитата(GIK @  7.2.2007,  00:58 Найти цитируемый пост)
значение данных хранимых, к примеру, в виртуальной области от 0x00000000 до 0x0000FFFF

user posted image
http://www.ozon.ru/context/detail/id/87878/
В этой книге рассказано и есть пример.

Советую найти (1998 год издания) и купить.

Автор: Sartorius 7.2.2007, 10:45
SergeCpp, а на соклько это все вообще может быть актуально? Ясно, что ХР на NT ядре, но с 1998 года многое могло измениться. Тем более "недокументированные возможности"

Автор: GIK 7.2.2007, 10:46
Все понятно, мне читать и читать. smile
Как насчет второго момента? Почему инкремент адреса дает тоже число что и значенрие хранимое по адресу , до инкремента?

Автор: Sartorius 7.2.2007, 10:52
Цитата

Почему инкремент адреса дает тоже число что и значенрие хранимое по адресу , до инкремента? 


 Рискну предположить, что там лежит это же число...  smile 

Автор: vinter 7.2.2007, 11:51
Цитата
Интерес чисто познавательный, а каким образом он будет ругаться?


студия вылетает с ошибкой

Автор: Anikmar 7.2.2007, 13:40
Цитата(vinter @  7.2.2007,  11:51 Найти цитируемый пост)
студия вылетает с ошибкой 

Т.е. Студия при компиляции ругнется на такой код?
Код

int MyFun(void)
{
  int *p;

  *p = 25;

 return *p;
}


Вообще-то максимум предупреждение должно быть - на то оно и Си (в смысле сотворить можно что угодно)

Автор: GIK 7.2.2007, 15:59
Цитата

Рискну предположить, что там лежит это же число...   

Ага  smile прям в точку, иначе и быть не может smile  Тоько вот вопрос, как оно туба попало так удачно  smile  

Автор: vinter 7.2.2007, 18:36
Цитата
Т.е. Студия при компиляции ругнется на такой код?


да, вылетит с ошибкой
Цитата

Вообще-то максимум предупреждение должно быть - на то оно и Си (в смысле сотворить можно что угодно)

на то он и компилятор, чтобы не давать творить ерунду всякую smile , от которой потом роковые ошибки вылазят..

Автор: Anikmar 7.2.2007, 18:45
Цитата(vinter @  7.2.2007,  18:36 Найти цитируемый пост)
на то он и компилятор, чтобы не давать творить ерунду всякую  , от которой потом роковые ошибки вылазят.. 

Это не всегда ошибка. Не должен вылететь компилятор - проверьте. Поясню на примере:
Код

int MyFun(void)
{
  int *p;
  int **pp = &p;
  int a;
  *pp = &a;

  *p = 25;

 return *p;
}



Сдесь никакой ошибки нет - вот захотелось так программеру...

Автор: vinter 7.2.2007, 19:02
Цитата

Сдесь никакой ошибки нет - вот захотелось так программеру...

а тут и не вылетает.. а вот там была ошибка..
кстати так и не понял почему у p и *pp, стали одинаковые адреса ведь мы же поменяли значение указателя *pp, и он стал указывать на другую область памяти, почему *p поменялся?? 

Автор: GIK 7.2.2007, 19:16
А вот меня болше интересует почему одинаковые данные вылазят, тут явно что то нето....

Автор: Anikmar 7.2.2007, 20:19
Цитата(GIK @  6.2.2007,  22:58 Найти цитируемый пост)
Очень интересно наблюдать, когда выкидывает одинаковые числа 

Цитата(GIK @  7.2.2007,  19:16 Найти цитируемый пост)
А вот меня болше интересует почему одинаковые данные вылазят, тут явно что то нето.... 

Мы немного отвлеклись от основного вопроса топика (совсем немного, на самом деле). 
При переносе указанного кода в мой Билдер были выданы разные числа....
Поэтому списываю на совпадение, хотя формат вывода целого числа и указателя явно должны отличаться.
В Билдере выводятся разные числа, НО: они выводятся совершенно по-разному - формат у указателя и int разный...

Добавлено @ 20:22 
Цитата(vinter @  7.2.2007,  19:02 Найти цитируемый пост)
кстати так и не понял почему у p и *pp, стали одинаковые адреса ведь мы же поменяли значение указателя *pp, и он стал указывать на другую область памяти, почему *p поменялся??  

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

Ну не должен компилятор на это ругаться! Он может предупредить, но ругаться нельзя - это не ошибка, это может так задумано было (конечно больным на голову программистом) - но могло.

Автор: threef 7.2.2007, 21:13
Че-йто совсем я не понимаю.
Код

void *p;
int x=5;
p=&x;
cout<<*p; 


это что, попытка взглянуть на void ?

Автор: Anikmar 7.2.2007, 21:21
Цитата(threef @  7.2.2007,  21:13 Найти цитируемый пост)
Че-йто совсем я не понимаю.

код C++
void *p;
int x=5;
p=&x;
cout<<*p; 

это что, попытка взглянуть на void ? 


Вот на это точно должен ругаться компилятор. Указатель на void НЕ РАЗЫМЕНОВЫВАЕТСЯ!

Автор: threef 7.2.2007, 21:43
Да что ты! А в первом посте что, g - это не указатель на void ? не его ли пытаются разыменовать ? а 0 - ffff - это указатели, зарезервированные системой виртуальной памяти как NULL - указатели, и ничего оттуда не выудить. Разве что в обход этой самой системы. И Це здесь ни причем.

Автор: Anikmar 7.2.2007, 21:48
Цитата(threef @  7.2.2007,  21:43 Найти цитируемый пост)
Да что ты! А в первом посте что, g - это не указатель на void ? не его ли пытаются разыменовать ? а 0 - ffff - это указатели, зарезервированные системой виртуальной памяти как NULL - указатели, и ничего оттуда не выудить. Разве что в обход этой самой системы. И Це здесь ни причем. 

Упс... А слона я и не заметил!
Я начал читать не с первой строчки первого поста и что-то увлекся теорией!  smile (ну невнимательный я!)

Ну, мои посты особо этому не противоречат  smile 

Виноват-с-с-с... Обмишурился.... smile 

Автор: W4FhLF 8.2.2007, 13:36
Цитата(GIK @  6.2.2007,  22:58 Найти цитируемый пост)
Компилятор не дает значение данных хранимых, к примеру, в виртуальной области от 0x00000000 до 0x0000FFFF



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

Автор: GIK 8.2.2007, 17:57
W4FhLF, спасибо конечно, но я это перечитал уже smile
Как грица, чем дальше в лес тем шире партизаны smile
Вот еще один не менее занимательный момент, у меня, кроме того что вылетает одинаковые числа (я закоментировал какие), еше разница в адресах имеет непонятную разницу. После инкремента указателя и декремента сразу, она равна 12, а после просто инкремента, она равна 4. Вобщем сдесь видно:
Компилятор - булдер 6.0. Может он устарел?
Код

#include<conio>
#include<iostream>
using namespace std;

int main()
{

    int *g1;
    int p1=123;
    g1=&p1;
    g1++;
    cout<<g1<<endl;   //1245064
    cout<<*g1<<endl;  //1245064

  //  а теперь инкремент и декремент
   // есть разница = 12 между адресами указателя и значение выводит правильное
    int *g2;
    int p2=12345;
    g2=&p2;
    g2++;
    g2--;
    cout<<g2<<endl;   //1245052
    cout<<*g2<<endl;  //12345

   // а теперь разница в указателях = 4, что вобшем-то и логично :)
    int *g3;
    int p3=12345;
    g3=&p3;
    g3++;
    //g3--;
    cout<<g3<<endl;   //1245048
    cout<<*g3<<endl;  //1245048


    getche();
        return 0;


}

Автор: Anikmar 8.2.2007, 18:11
Думаю все дело в выводе на экран. Если заменить cout на printf все нормально.
Под отладчиком тоже все впорядке

Автор: W4FhLF 8.2.2007, 18:25
Цитата(GIK @  8.2.2007,  17:57 Найти цитируемый пост)
но я это перечитал уже


Тогда в чём вопрос изначально заключается? 

Автор: GIK 8.2.2007, 18:34
Ну я вообщето хотел доступ открыть smile Глупо наверное, но а вдруг кто знает как?  Может через виндовые функции?

Добавлено @ 18:38 
Меня вообщето еще масса вопросов мучает, но чувствую, если модера заметят, что я их задаю, будут ругатся smile

Автор: Anikmar 8.2.2007, 18:53
 smile 
Странно, почему мое сообщение закрыли? Матного там нет - грубовато конечно, но в шутливом же аспекте...
Цитата(Anikmar @  7.2.2007,  21:48 Найти цитируемый пост)
Сообщение скрыто модератором: SergeCpp +
Причина: временно


Автор: W4FhLF 8.2.2007, 18:59
Цитата(GIK @  8.2.2007,  18:34 Найти цитируемый пост)
Ну я вообщето хотел доступ открыть 


К несуществующему в физической памяти участку? Там нет ничего, ни виртуально, ни физическиsmile

Автор: SergeCpp 8.2.2007, 19:28
Цитата(Anikmar @  8.2.2007,  20:53 Найти цитируемый пост)
Странно, почему мое сообщение закрыли?

Вы ПМ читаете?.. Одно Вам отправлено при скрытии и одно я отправил. Прочтите их.

Автор: Anikmar 8.2.2007, 19:47
Цитата(SergeCpp @  8.2.2007,  19:28 Найти цитируемый пост)
Вы ПМ читаете?.. Одно Вам отправлено при скрытии и одно я отправил. Прочтите их.

Точно! Тут же ящик есть - забыл совсем.

Исправился - больше не буду.
По крайней мере постараюсь.

Какой хороший форум - даже себя обзывать нельзя!  smile 

Автор: SergeCpp 8.2.2007, 20:03
Цитата(GIK @  8.2.2007,  20:34 Найти цитируемый пост)
Меня вообщето еще масса вопросов мучает, но чувствую, если модера заметят, что я их задаю, будут ругатся

По теме памяти задавайте! user posted image

http://sergecpp.mylivepage.ru/file/6/218/ user posted image

Автор: GIK 8.2.2007, 22:51
О, какой приятный сюрпризик, однако smile Вот уж сенькью, так сенькью smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)