diff --git a/src/ch05.md b/src/ch05.md index 101e8df..31e3491 100644 --- a/src/ch05.md +++ b/src/ch05.md @@ -10,7 +10,7 @@ (например, прочитать файл), может запросто использовать несколько сотен мегабайт памяти, сделать что-то потрясающее и далее выйти. По выходу операционная система освобождает все ресурсы (память, в частности), -которые были исопльзованы программой, пока она выполнялась. Освобожденная +которые были использованы программой, пока она выполнялась. Освобожденная память затем может быть отдана в пользование другим программам. Однако, для программ, которые работают днями, месяцами и даже годами, @@ -18,7 +18,7 @@ далеко не только какой-то отдельно взятой программе, но и другим, исполняющимся на этой же машине. То есть попросту невозможно ждать, пока какая-то программа не завершится и память станет доступной. Многие языки -программиования имеют среду времени выполнения, в которую входит сборщик +программирования имеют среду времени выполнения, в которую входит сборщик мусора - его первейшая задача как раз и есть отслеживание более не нужной памяти и её освобождение. Как уже пару раз упоминалось в предыдущих главах, в Zig нет сборщика мусора, поэтому его роль выполняет разработчик @@ -28,7 +28,7 @@ область, где хранятся данные, не подлежащие модификации, то есть константы, включая строковые. Эти данные содержатся в исполнимом файле. Такие данные существуют (то есть занимают память) всё время выполнения -программы, причём объём занимаемой имм памяти остаётся постоянным, он не +программы, причём объём занимаемой ими памяти остаётся постоянным, он не может ни увеличиться, ни уменьшится. Но это не то, о чём нас следует беспокоиться, разве что общее количество таких данных сказывается на размере исполнимого файла. @@ -47,9 +47,9 @@ переменная доступна только в той области видимости, где она была объявлена. В Zig области видимости это, по сути, блоки кода, окружённые фигурными скобками (`{ ... }`). Большинство переменных привязаны или к -функции (включая её аргументы), или к управляющим констркуциям, таким +функции (включая её аргументы), или к управляющим конструкциям, таким как, например, `if`. Однако, как мы видели, можно создавать любые блоки и -тем самым, проивольные области видимости. +тем самым, произвольные области видимости. В предыдущей главе мы визуализировали содержимое памяти для функций `main` и `levelUp`, используя экземпляры переменной типа `User`: @@ -136,7 +136,7 @@ main: user -> ------------- (id: 1043368d0) В обычных программах стек довольно сильно заполнен, поскольку типичная программа использует множество библиотек, и как следствие глубина вложенности вызовов функций может быть достаточно большой. Обычно это не -является проблемой, но иногда можно довести дело до переполения стека. +является проблемой, но иногда можно довести дело до переполнения стека. Зачастую это случается с рекурсивными функциями, то есть функциями, вызывающими саму себя. @@ -149,14 +149,14 @@ main: user -> ------------- (id: 1043368d0) Выделение памяти на стеке и её освобождение это очень быстрые операции, поскольку это всего лишь декремент/инкремент указателя вершины стека -(обычно стек "растёт" в сторону меньшмх адресов памяти). +(обычно стек "растёт" в сторону меньших адресов памяти). ## "Висячие" указатели (dangling pointers) Стек вызовов это замечательный механизм в силу его простоты и эффективности. Однако нас должно насторожить следующее обстоятельство: когда функция завершает работу, всё её локальные переменные как бы исчезают. -Это, по идее, разумно, в конце концов, это же лоакльные переменные, +Это, по идее, разумно, в конце концов, это же локальные переменные, они нужны только самой функции, но есть одно но. Рассмотрим следующий пример: ```zig @@ -217,7 +217,7 @@ User 16777216 has power of -1 Почему так происходит? Дело в том, что функция `User.init` возвращает **адрес локальной переменной**, то есть `&user`. Это называется "висячий" указатель, источник многих проблем, вплоть до аварийного завершения или, -по крайней мере, как мы только что виделм, явно некорректное поведения программы. +по крайней мере, как мы только что видели, явно некорректное поведения программы. Когда стековый кадр "уничтожается", всякие ссылки в ту область памяти, которую этот кадр занимал, становятся попросту бессмысленными. И что мы