Теоретично, ми мали б змогу передавати вказівники як рядки?

текст перекладу
Я пишу цей пост, припускаючи, що кожен, хто його читає, розуміє мову програмування C++.

Короткий огляд вказівників

Вказівники — це просто адреси пам'яті. У сучасних системах це зазвичай віртуальні адреси. Це означає, що вони не вказують безпосередньо на фізичну пам'ять (як RAM), а проходять через процес відображення. Подумайте про віртуальні адреси як про координати на карті, які система транслює в фактичне фізичне місце.

Ось швидка діаграма, яку я створив, щоб пояснити свої думки.

pic

Серіалізація (і десеріалізація)

Серіалізація — це процес перетворення даних у пам'яті в формат, який можна зберігати або передавати, наприклад, рядок або бінарний файл. Це схоже на створення знімка об'єкта або змінної та збереження його для подальшого використання.

Десеріалізація — це зворотний процес. Вона приймає збережений формат (рядок, бінарний тощо) і відновлює оригінальні дані в пам'яті. Це схоже на завантаження вашого знімка назад у використовуючи форму.

Перетворення вказівників у рядки (і назад)

Ми можемо взяти вказівник, перетворити його в рядок (серіалізувати), а потім перетворити його назад у вказівник (десеріалізувати). Ось простий приклад на C++:

Код серіалізації:

#include   
#include  // Для std::stringstream  
#include  // Для std::string  

std::string serializePointer(int* pointer) {  
 uintptr_t addressAsInt = reinterpret_cast(pointer);  
 std::stringstream ss;  
 ss << std::hex << addressAsInt; // Перетворити в шістнадцятковий формат для зручності  
 return ss.str();  
}  

int main() {  
 // Крок 1: Визначити змінну та отримати її адресу  
 int myVariable = 42;  
 int* originalPointer = &myVariable;  

 // Серіалізувати вказівник  
 std::string serializedAddress = serializePointer(originalPointer);  
 std::cout << "Serialized Address: " << serializedAddress << std::endl;  

 return 0;  
}

Код десеріалізації:

#include   
#include  // Для std::stringstream  
#include  // Для std::string  

int* deserializePointer(const std::string& serializedAddress) {  
 uintptr_t deserializedInt;  
 std::stringstream ss(serializedAddress);  
 ss >> std::hex >> deserializedInt;  
 return reinterpret_cast(deserializedInt);  
}  

int main() {  
 // Імітуємо отримання серіалізованої адреси (замінити на фактичне серіалізоване значення)  
 std::string serializedAddress = "2c8e3ffca0"; // Приклад значення; замініть на вашу серіалізовану адресу  

 // Десеріалізувати вказівник  
 int* deserializedPointer = deserializePointer(serializedAddress);  

 // Доступ або зміна значення змінної за допомогою десеріалізованого вказівника  
 std::cout << "Значення myVariable через десеріалізований вказівник: "   
 << *deserializedPointer << std::endl;  

 *deserializedPointer = 99; // Змінити значення через вказівник  
 std::cout << "Змінене значення myVariable: " << *deserializedPointer << std::endl;  

 return 0;  
}

Передача між процесами

Теоретично ми повинні мати змогу серіалізувати адресу пам'яті, передати її в інший процес за допомогою якогось методу комунікації (наприклад, REST API, сокети або навіть протоколи комунікації між процесами, такі як тунелі) і здійснити десеріалізацію, щоб прочитати дані за цією адресою.

На жаль, це неможливо. Раніше я розповідав, що кожен процес має свою власну таблицю віртуальних адрес, яка відображає реальну фізичну адресу в RAM.

Оскільки кожен процес має свою унікальну таблицю віртуальних адрес пам'яті, адреса, яку ви отримуєте, серіалізуєте та відправляєте з одного процесу, не буде мати таке саме значення у віртуальній адресній таблиці, навіть якщо її можна десеріалізувати.

Перекладено з: In Theory, We Should Be Able To Pass Pointers As Strings?

Leave a Reply

Your email address will not be published. Required fields are marked *