On branch main
modified: src/ch06.md new file: src/ex-ch06-05.zig
This commit is contained in:
74
src/ch06.md
74
src/ch06.md
@@ -16,13 +16,13 @@
|
||||
модифицированы), переменные в стеке живут, пока работает функция, который
|
||||
принадлежит этот стековый кадр.
|
||||
|
||||
Эта глава посвящена двум темам. Первая это общий обзор нашей третьей области
|
||||
памяти, кучи. А вот вторая более интересна - в языке Zig имеется вполне
|
||||
ясный, но тем не менее уникальный подход к управлению динамической
|
||||
памятью. Даже если Вы так или иначе умеете работать с кучей
|
||||
(например, при помощи `malloc` и `free` из стандартной библиотеки языка C),
|
||||
Вам всё равно следует проштудировать эту главу, поскольку в Zig
|
||||
есть свои особенности.
|
||||
Эта глава посвящена двум темам. Первая это общий обзор нашей третьей
|
||||
области памяти, кучи. А вот вторая более интересна - в языке Zig имеется
|
||||
концептуально простой, но тем не менее уникальный подход к управлению
|
||||
динамической памятью. Даже если Вы так или иначе умеете работать с кучей
|
||||
(например, при помощи `malloc` и `free` из стандартной библиотеки языка
|
||||
C), Вам всё равно следует проштудировать эту главу, поскольку в Zig есть
|
||||
свои особенности.
|
||||
|
||||
## Динамическая память (heap, "куча")
|
||||
|
||||
@@ -754,5 +754,63 @@ defer list.deinit();
|
||||
И если бы где-то в `intList` создавался бы ещё один аллокатор с регионами,
|
||||
то это тоже бы сработало, поскольку никто не запрещает иметь арену внутри арены.
|
||||
|
||||
## Распределитель с фиксированным буфером
|
||||
|
||||
Последний аллокатор, который мы изучим, это `std.heap.FixedBufferAllocator`,
|
||||
который выделяет место под объекты в буфере (то есть в `[]u8`), который
|
||||
ему предоставляется при инициализации. У этого аллокатора есть два главных преимущества.
|
||||
Во-первых, поскольку память уже выделена заранее, это быстро. Во-вторых,
|
||||
он естественным образом ограничивает максимальный размер выделяемой памяти,
|
||||
что, с другой стороны, может считаться недостатком. Другой недостаток
|
||||
состоит в том, что `free` и `destroy` у этого аллокатора работают только
|
||||
с последним размещённым объектом (практически, как в стеке).
|
||||
Попытка удаления не последнего объекта абсолютна безопасна, поскольку
|
||||
такое удаление просто ничего не делает.
|
||||
|
||||
```zig
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
var buf: [150]u8 = undefined;
|
||||
var fa = std.heap.FixedBufferAllocator.init(&buf);
|
||||
defer fa.reset();
|
||||
|
||||
const allocator = fa.allocator();
|
||||
|
||||
const json = try std.json.stringifyAlloc(allocator, .{
|
||||
.this_is = "an anonymous struct",
|
||||
.above = true,
|
||||
.last_param = "are options",
|
||||
}, .{.whitespace = .indent_2});
|
||||
|
||||
std.debug.print("{s}\n", .{json});
|
||||
}
|
||||
```
|
||||
|
||||
Этот пример напечает
|
||||
|
||||
```
|
||||
{
|
||||
"this_is": "an anonymous struct",
|
||||
"above": true,
|
||||
"last_param": "are options"
|
||||
}
|
||||
```
|
||||
|
||||
Уменьшите размер буфера (сделайте `[120]u8` вместо `[150]u8`) и вы получите ошибку:
|
||||
|
||||
```
|
||||
error: OutOfMemory
|
||||
...
|
||||
```
|
||||
|
||||
Общеупотребительной является практика, когда буфер приводится в исходное
|
||||
состояние (при помощи метода `reset`) и затем снова используется.
|
||||
Это также относится и к `ArenaAllocator`, хотя и в меньшей степени.
|
||||
|
||||
## Заключение
|
||||
|
||||
Отсутствие в Zig аллокатора по умолчанию делает его прозрачным и гибким
|
||||
в отношении управления памятью. Интерфейс `std.mem.Allocator` позволяет
|
||||
строить специализиованные аллокаторы на основе более общих.
|
||||
|
||||
## FixedBufferAllocator
|
||||
|
||||
18
src/ex-ch06-05.zig
Normal file
18
src/ex-ch06-05.zig
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
var buf: [150]u8 = undefined;
|
||||
var fa = std.heap.FixedBufferAllocator.init(&buf);
|
||||
defer fa.reset();
|
||||
|
||||
const allocator = fa.allocator();
|
||||
|
||||
const json = try std.json.stringifyAlloc(allocator, .{
|
||||
.this_is = "an anonymous struct",
|
||||
.above = true,
|
||||
.last_param = "are options",
|
||||
}, .{.whitespace = .indent_2});
|
||||
|
||||
std.debug.print("{s}\n", .{json});
|
||||
}
|
||||
Reference in New Issue
Block a user