On branch main
modified: src/ch05.md
This commit is contained in:
12
src/ch05.md
12
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), ручное управление памятью может поначалу
|
||||
показаться чем-то трудным, что чревато ошибками в программах и
|
||||
|
||||
Reference in New Issue
Block a user