Fix memory leak in demo, document arena allocator usage

This commit is contained in:
2026-01-19 12:11:45 +05:30
parent d48bc3dedd
commit c73fb2ed03
2 changed files with 27 additions and 5 deletions

View File

@@ -33,6 +33,8 @@ exe.root_module.addImport("pugz", pugz.module("pugz"));
## Usage ## Usage
**Important:** Always use an arena allocator for rendering. The render function creates many small allocations that should be freed together. Using a general-purpose allocator without freeing will cause memory leaks.
```zig ```zig
const std = @import("std"); const std = @import("std");
const pugz = @import("pugz"); const pugz = @import("pugz");
@@ -54,6 +56,25 @@ pub fn main() !void {
} }
``` ```
### With http.zig
When using with http.zig, use `res.arena` which is automatically freed after each response:
```zig
fn handler(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
const html = app.view.render(res.arena, "index", .{
.title = "Hello",
}) catch |err| {
res.status = 500;
res.body = @errorName(err);
return;
};
res.content_type = .HTML;
res.body = html;
}
```
### Template String ### Template String
```zig ```zig

View File

@@ -75,7 +75,8 @@ pub fn main() !void {
/// Handler for GET / /// Handler for GET /
fn index(app: *App, _: *httpz.Request, res: *httpz.Response) !void { fn index(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
const html = app.view.render(app.allocator, "index", .{ // Use res.arena - memory is automatically freed after response is sent
const html = app.view.render(res.arena, "index", .{
.title = "Home", .title = "Home",
.authenticated = true, .authenticated = true,
}) catch |err| { }) catch |err| {
@@ -90,7 +91,7 @@ fn index(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
/// Handler for GET /page-a - demonstrates extends and block override /// Handler for GET /page-a - demonstrates extends and block override
fn pageA(app: *App, _: *httpz.Request, res: *httpz.Response) !void { fn pageA(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
const html = app.view.render(app.allocator, "page-a", .{ const html = app.view.render(res.arena, "page-a", .{
.title = "Page A - Pets", .title = "Page A - Pets",
.items = &[_][]const u8{ "A", "B", "C" }, .items = &[_][]const u8{ "A", "B", "C" },
.n = 0, .n = 0,
@@ -106,7 +107,7 @@ fn pageA(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
/// Handler for GET /page-b - demonstrates sub-layout inheritance /// Handler for GET /page-b - demonstrates sub-layout inheritance
fn pageB(app: *App, _: *httpz.Request, res: *httpz.Response) !void { fn pageB(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
const html = app.view.render(app.allocator, "page-b", .{ const html = app.view.render(res.arena, "page-b", .{
.title = "Page B - Sub Layout", .title = "Page B - Sub Layout",
}) catch |err| { }) catch |err| {
res.status = 500; res.status = 500;
@@ -120,7 +121,7 @@ fn pageB(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
/// Handler for GET /append - demonstrates block append /// Handler for GET /append - demonstrates block append
fn pageAppend(app: *App, _: *httpz.Request, res: *httpz.Response) !void { fn pageAppend(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
const html = app.view.render(app.allocator, "page-append", .{ const html = app.view.render(res.arena, "page-append", .{
.title = "Page Append", .title = "Page Append",
}) catch |err| { }) catch |err| {
res.status = 500; res.status = 500;
@@ -134,7 +135,7 @@ fn pageAppend(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
/// Handler for GET /append-opt - demonstrates optional block keyword /// Handler for GET /append-opt - demonstrates optional block keyword
fn pageAppendOptional(app: *App, _: *httpz.Request, res: *httpz.Response) !void { fn pageAppendOptional(app: *App, _: *httpz.Request, res: *httpz.Response) !void {
const html = app.view.render(app.allocator, "page-appen-optional-blk", .{ const html = app.view.render(res.arena, "page-appen-optional-blk", .{
.title = "Page Append Optional", .title = "Page Append Optional",
}) catch |err| { }) catch |err| {
res.status = 500; res.status = 500;