Статическая локальная переменная, не занимающая физической памяти - PullRequest
1 голос
/ 17 марта 2019

Я создал следующие функции для проверки использования памяти статическими локальными переменными и ожидал, что массив займет примерно 5 МБ памяти, но когда я его запустил, использование физической памяти процессом составило всего 0,2 МБ и увеличилось, когда яфактически устанавливаю значение для каждого элемента в массиве.

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

void func() {
  static char a[5000000];
  a[0] = 'a';
  a[4999999] = 'a';
  cin >> a;
}

int main(int argc, char const *argv[]) {
  func();
  return 0;
}

1 Ответ

1 голос
/ 17 марта 2019

Это связано с отложенным выделением памяти или заполнением нуля по требованию , как описано ниже.

Это объясняется в инициализации нуля at cppreference:

Инициализация нуля выполняется в следующих ситуациях:

1 Для каждой именованной переменной со статическим или локальным потоком хранения, которая не подлежит постоянной инициализации (так какC ++ 14), перед любой другой инициализацией.

Таким образом, эта переменная квалифицируется.Что это означает инициализация нуля :

Эффект инициализации нуля:

  • Если T - скалярный тип, начальное значение объекта равноцелочисленная константа ноль явно преобразуется в T.
  • [...] Если T является типом массива, каждый элемент инициализируется нулями

В качестве оптимизации наиболее современныйсистемы даже не выделяют память для инициализируемых нулем глобальных / статических переменных, и поэтому размер массива не влияет на использование памяти.Что происходит вместо этого, исполняемый файл имеет метку, которая гласит: «здесь должны быть нулевые значения», и ничего более.Когда программа загружается, все адреса отображаются в небольшой и общий блок физической памяти, доступный только для чтения, который содержит нули.

Несколько виртуальных адресов могут отображаться в одну и ту же память через аппаратное обеспечение в ЦП, которое называется « Блок управления памятью » (MMU).Когда код пытается записать адрес в диапазоне, MMU уведомляет операционную систему (ОС), что кто-то записывает блок памяти только для чтения, и ОС выделяет память только тогда

...