diff --git a/src/ch05.md b/src/ch05.md index 31e3491..31da04b 100644 --- a/src/ch05.md +++ b/src/ch05.md @@ -140,7 +140,7 @@ main: user -> ------------- (id: 1043368d0) Зачастую это случается с рекурсивными функциями, то есть функциями, вызывающими саму себя. -Стек, как и сегмент данных, управляется операционной системой, Новый стек +Стек, как и сегмент данных, управляется операционной системой. Новый стек вызовов создаётся при запуске процесса, а также при создании этим процессом новых потоков выполнения (нитей, threads). Размер стека обычно можно настроить. Стек вызовов существует всё время работы процесса или @@ -209,7 +209,7 @@ User 2 has power of 2 то мы вообще можем увидеть какую-то несусветную чушь: ``` -s$ ./ex-ch05-01 +$ ./ex-ch05-01 User 2105973 has power of 704957192 User 16777216 has power of -1 ``` @@ -217,7 +217,7 @@ User 16777216 has power of -1 Почему так происходит? Дело в том, что функция `User.init` возвращает **адрес локальной переменной**, то есть `&user`. Это называется "висячий" указатель, источник многих проблем, вплоть до аварийного завершения или, -по крайней мере, как мы только что видели, явно некорректное поведения программы. +по крайней мере, как мы только что видели, явно некорректного поведения программы. Когда стековый кадр "уничтожается", всякие ссылки в ту область памяти, которую этот кадр занимал, становятся попросту бессмысленными. И что мы @@ -254,11 +254,11 @@ fn read() !void { Видите потенциальные проблемы? То, что возвращает `Parser.parse`, чем бы оно не являлось, явно "переживает" (outlives) `input`. Если `Parser` содержит ссылку на `input`, то это будет висячей ссылкой, которая будет -коварно ждать, чтобы обрушить нашу программу.В идеале, если переменной +коварно ждать, чтобы обрушить нашу программу. В идеале, если переменной типа `Parser` нужен `input`, который будет существовать столь же долго, как и она сама, `Parser` сделает копию и эта копия будет привязана к его собственному *времени жизни* (подробнее об этом будет в следующей главе). -Но тут нет чего, что способствовало соблюдению такого соглашения. +Но тут нет ничего, что способствовало бы соблюдению такого соглашения. Возможно, гипотетическая документация к типу `Parser`может прояснить, что он ожидает от `input` или что он с ним делает. Если же документации нет, то, скорее всего, нам придётся углубиться в код, чтобы выяснить всё это. @@ -273,7 +273,7 @@ user`, а не `return &user`. Но это не всегда оказывает Прежде чем погрузиться в тему динамического выделения памяти, небольшое забегание вперёд: в этой книге вы увидите ещё один пример висячих указателей. К тому моменту мы уже будем знать достаточно, чтобы привести -менее ... пример. К этой теме важно будет вернуться потому, что для +менее надуманный пример. К этой теме важно будет вернуться потому, что для разработчиков, которые раньше не имели дела с языками без автоматической сборки мусора (например, C), ручное управление памятью может поначалу показаться чем-то трудным, что чревато ошибками в программах и