Skip to content

Instantly share code, notes, and snippets.

@oconnor663
Created January 28, 2022 17:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oconnor663/7fa4bc3b44546707a9977c62a7ce6f48 to your computer and use it in GitHub Desktop.
Save oconnor663/7fa4bc3b44546707a9977c62a7ce6f48 to your computer and use it in GitHub Desktop.
An example of how defer/errdefer interacts with ownership.
const std = @import("std");
const Allocator = std.mem.Allocator;
const ArrayList = std.ArrayList;
const Person = struct {
pet: Pet,
const Self = @This();
// Takes ownership of pet.
pub fn init(pet: Pet) !Self {
return Self{ .pet = pet };
}
pub fn deinit(self: *Self) void {
self.pet.deinit();
}
const PlayError = error{
Oops,
};
pub fn play_with_pet(self: *Self) PlayError!void {
std.debug.print("{s}\n", .{self.pet.sound});
if (std.crypto.random.boolean()) {
return PlayError.Oops;
}
}
};
const Pet = struct {
sound: []u8,
const Self = @This();
pub fn init() !Self {
return Self{
.sound = try std.fmt.allocPrint(
std.heap.c_allocator,
"woof",
.{},
),
};
}
pub fn deinit(self: *Self) void {
std.heap.c_allocator.free(self.sound);
}
};
pub fn main() !void {
var fido = try Pet.init();
errdefer fido.deinit();
// Alice takes ownership of Fido.
var alice = try Person.init(fido);
defer alice.deinit();
try alice.play_with_pet();
}
@oconnor663
Copy link
Author

oconnor663 commented Jan 28, 2022

This program crashes with a double-free when play_with_pet fails on line 59.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment