MyTetra Share
Делитесь знаниями!
Миф №12: доступ к невыделенной памяти приводит к возбуждению Access Violation
Время создания: 06.10.2015 10:46
Раздел: Компьютер - Windows - Архитектура Windows - Архитектура памяти в Windows: мифы и легенды
Запись: xintrea/mytetra_syncro/master/base/1444117276mevou39bfe/text.html на raw.github.com

Миф №12: доступ к невыделенной памяти приводит к возбуждению Access Violation

Гм, разве каждый ребёнок не знает про то, что прежде чем использовать память, её надо выделить? Попытка доступа к невыделенной памяти неизменно закончится ошибкой доступа к памяти. Звучит разумно и миф кажется правдоподобным. Но давайте посмотрим, так ли это на самом деле:



1

2

3

4

5

6

7

8

9

10

11

12

13

14

program Project1;

 

{$APPTYPE CONSOLE}

 

uses

  Windows;

 

var

  P: Pointer;

begin

  P := VirtualAlloc(nil, 1024, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);

  FillChar(P^, 2 * 1024, 0);

  ReadLn;

end.


Чтобы исключить влияние менеджера памяти Delphi, мы выделяем память не через GetMem / AllocMem, а прося её напрямую у системы - через VirtualAlloc. Суть примера в том, что мы выделяем 1 Кб памяти (1024 байт), а потом записываем в них 2 Кб. Казалось бы, это должно привести к возбуждению Access Violation, но при запуске программы мы обнаруживаем, что она успешно выполняется до конца.

В чём же дело? Как мы помним, выделение памяти происходит с гранулярностью в 64 Кб, а размер выделяемых блоков кратен размеру страницы - т.е. 4 Кб. Да, это странное поведение (почему бы не выделять память с гранулярностью в 4 Кб?), но у него есть причины. Но это означает, что если вы просите у системы 1 Кб, то будет выделено все 4 Кб, а 60 Кб, следующие за этой страницей, останутся неиспользуемыми (ведь следующий блок памяти может начинаться лишь на границе +64 Кб от текущего).

Вот и причина для успешного выполнения этого кода - на самом деле код программы выделяет не 1 Кб, а 4 Кб. Это легко можно подтвердить, если заменить множитель 2 в FillChar на 5: 5 Кб больше 4 Кб, поэтому теперь программа вылетит.

Несмотря на это, миф нельзя назвать полностью разрушенным, ведь технически эта память выделена - даже хотя вы логически этого не просили. Поэтому я бы назвал его "правдоподобным".

Статус мифа: plausible.

Так же в этом разделе:
 
MyTetra Share v.0.65
Яндекс индекс цитирования