On branch main

modified:   src/ch05.md
This commit is contained in:
zed
2023-11-21 12:08:15 +03:00
parent d659cd4c5a
commit 75a14a299c

View File

@@ -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), ручное управление памятью может поначалу
показаться чем-то трудным, что чревато ошибками в программах и