Address Sanitizers from c can do more as far as I know, but the std.heap.GeneralPurposeAllocator
can detect memory leaks and at least in my small test case did crash upon trying to free the memory twice, although that happened mostly because it just tried to memset memory it no longer owns to 0, so I dont know if this works reliably in every case. It does not, however, detect things such as use after free.
Tools like valgrind do however work on zig, although in my experience not always on debug builds (meaning you might have to use a ReleaseSafe build)
pub fn main() !void {
var alloc_impl: std.heap.GeneralPurposeAllocator(.{}) = .init;
defer _ = alloc_impl.deinit();
const allocator = alloc_impl.allocator();
const memory = try allocator.alloc(u8, 8);
allocator.free(memory);
_ = memory[4];
allocator.free(memory);
}
const std = @import("std");
Segmentation fault at address 0x7f3f622ac000
/home/markus/.local/share/zigup/0.14.0-dev.2577+271452d22/files/lib/compiler_rt/memset.zig:19:14: 0x10f18a0 in memset (compiler_rt)
d[0] = c;
^
/home/markus/.local/share/zigup/0.14.0-dev.2577+271452d22/files/lib/std/mem/Allocator.zig:314:26: 0x103b5a3 in free__anon_2160 (main)
@memset(non_const_ptr[0..bytes_len], undefined);
^
/home/markus/main.zig:9:19: 0x103b140 in main (main)
allocator.free(memory);
^
/home/markus/.local/share/zigup/0.14.0-dev.2577+271452d22/files/lib/std/start.zig:656:37: 0x103af92 in posixCallMainAndExit (main)
const result = root.main() catch |err| {
^
/home/markus/.local/share/zigup/0.14.0-dev.2577+271452d22/files/lib/std/start.zig:271:5: 0x103ab7d in _start (main)
asm volatile (switch (native_arch) {
^
???:?:?: 0x0 in ??? (???)
[1] 11609 IOT instruction zig run main.zig
I hope that this information is helpful