Почему адреса локальных переменных могут отличаться каждый раз?

Я спросил Google и провел некоторое исследование по StackOverflow. Мой вопрос заключается в том, что, когда я вхожу в main() функционировать в программе на C ++ и объявлять самую первую переменную, почему адрес этой переменной может варьироваться в зависимости от выполнения? Пожалуйста, смотрите мой пример программы ниже:

#include <iostream>

int main() {
int *a = new int;
int *b = new int;

std::cout << "address: " << a << " " << b << std::endl;
std::cout << "address of locals: " << &a << " " << &b << std::endl;
return 0;
}

Результат по исполнению 1:

address: 0xa32010 0xa32030
address of locals: 0x7fff10de2cf0 0x7fff10de2cf8

Результат по исполнению 2:

address: 0x1668010 0x1668030
address of locals: 0x7ffc252ccd90 0x7ffc252ccd98

Результат по исполнению 3:

address: 0x10e0010 0x10e0030
address of locals: 0x7ffd3d2cf7f0 0x7ffd3d2cf7f8

Как видите, я получаю разные результаты при разных казнях. Первая строка вывода соответствует адресу выделенной памяти, что должно происходить в куче — если им каждый раз назначаются разные адреса, это мне как-то логично. Однако даже когда я печатаю адреса локальных переменных — в соответствии со второй строкой — результаты все равно разные.

На первый взгляд, я думал, что это потому, что программа печатает адрес физической памяти, но этот пост, Виртуальная память или физическая память, опровергает мою первоначальную мысль Есть ли какая-то причина, по которой выполнение программ «одинаково», без потоков, ввода пользователя и т. Д., Что по-прежнему есть выделения памяти с разными адресами?

Среда тестирования:

  • Linux 14.04
  • Mac OS X 10.10

8

Решение

При размещении в куче (используя new оператор или malloc() и друзья), ваша программа должна попросить ОС выделить вашу кучу памяти. Множество закулисных вещей происходит в диспетчере памяти ОС (детали реализации которого в основном выше моего уровня оплаты: сборка мусора, консолидация исправленной памяти и т. Д.), И это хорошая вещь не думать об этом.

Локальные переменные размещаются в стеке. Традиционно распределение стека повторяется, но в последние годы ситуация изменилась.
Рандомизация размещения адресного пространства (ASR) — сравнительно недавнее нововведение в управлении памятью ОС, которое намеренно делает адреса памяти при распределении стека (например, те, которые вы наблюдали) максимально недетерминированными во время выполнения. Это функция безопасности: это не позволяет плохим субъектам использовать переполнения буфера динамической памяти, потому что, если реализация ASLR достаточно энтропийна, кто знает, что будет в конце переполненного буфера?

Платой за эту и другие функции управления памятью является контроль. Ставки на адреса распределений на современной (не встроенной) платформе похожи на игру в Powerball: возможно, забавное отвлечение, но не осуществимый план на будущее. Если ваш код работает на платформе AVR-ISA или что-то подобное, возможно, шансы достаточно близки к Блэкджеку, так что кто-то может быть соблазн играть, чтобы выиграть (так сказать).

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

Благодаря @ T.C. за ссылку и @SergeyA за предложение.

11

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]