Указатели, указывающие на одно и то же место в памяти, но другую программу

#c #pointers

Вопрос:

Я написал две программы, одну (p1.cpp) , который выводит значение и адрес переменной каждые 1 секунду..

 // p1.cpp
int main() {

    int x = 13;
    int *p = amp;x;
    
    while (true) {
        cout << " value of x: " << *p << " addr: " << p << endl;
        sleep(1);
    }
}
 

а другой (p2.cpp), в котором я вручную указываю указатель на местоположение, распечатанное p1.cpp и измените значение.

 //p2.cpp
int main() {
    
    int *p = (int*)0x61ff08; // this is manually set and compiled.
    cout << "value of p from p2.cpp : " <<  *p << endl;
    *p = 10;
    
}
 

Однако при запуске p1.cpp, установка местоположения и запуск p2.cpp, значение в первой программе, похоже, не меняется. На самом деле, p2.cpp показывает некоторое значение мусора, если я отображаю содержимое p.

выход из p1.cpp

выход из p2.cpp

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

Спасибо!

Комментарии:

1. Скопируйте/вставьте выходные данные сюда, это сделает вопрос более легко читаемым.

2. Каждая программа имеет свою собственную виртуальную память. Указатели указывают на эту виртуальную память (предоставляемую ОС), а не на физическую память. Один и тот же адрес в двух программах всегда будет указывать на разную физическую память.

3. Возможно, вы читали о виртуальной памяти. Одинаковые значения адресов в разных процессах не означают, что они адресуются к одной и той же ячейке памяти.

4. подумайте, что происходит, когда вы дважды запускаете p1, вы можете напечатать один и тот же адрес дважды. Уже одно это может сказать вам, что это работает не совсем так, как вы ожидаете.

5. @Aswinpr если у вашего процесса есть правильные разрешения, вы можете использовать WriteProcessMemory для записи в память другого процесса. Но, как упоминали другие, если вы хотите взаимодействовать между программами, предпочтительнее использовать более типичные структурированные методы IPC.

Ответ №1:

В современных операционных системах, таких как linux, Windows или macOS, каждый процесс имеет свое собственное адресное пространство виртуальной памяти. Следовательно, адрес памяти процесса вашей программы p1 не имеет ничего общего с памятью процесса вашей программы p2.

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

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

Вы можете ознакомиться с этой статьей для первого ознакомления с темой: https://en.wikipedia.org/wiki/Inter-process_communication

Комментарии:

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

2. @Aswinpr Это возможно, если вы используете ОС с невиртуальной памятью (=операционная система с одним адресным пространством), например DOS, или используете эксплойт для прямого доступа к памяти других процессов (программ). Java-это другое дело, потому что она в основном работает на виртуальной машине Java (JVM) (хотя есть версии, которые этого не делают).