# How to check if a pointer is a single item or multi-item pointer to determine whether to call .free or .destroy

**URL:** <https://ziggit.dev/t/how-to-check-if-a-pointer-is-a-single-item-or-multi-item-pointer-to-determine-whether-to-call-free-or-destroy/7655>\
**Category:** Help\
**Tags:** memory-management, comptime\
**Created:** [January 3, 2025, 2:33am UTC](https://ziggit.dev/t/how-to-check-if-a-pointer-is-a-single-item-or-multi-item-pointer-to-determine-whether-to-call-free-or-destroy/7655 "2025-01-03T02:33:40Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![KeyboardSounds](https://ziggit.dev/user_avatar/ziggit.dev/keyboardsounds/32/4117_2.png) [@KeyboardSounds](https://ziggit.dev/u/KeyboardSounds)\
**Post date:** [January 3, 2025, 2:33am UTC](https://ziggit.dev/t/how-to-check-if-a-pointer-is-a-single-item-or-multi-item-pointer-to-determine-whether-to-call-free-or-destroy/7655/1 "2025-01-03T02:33:40Z")

</div>

Hi! I’m implementing a basic reference-counted pointer wrapper struct, `RcPtr`, to use in a WASM library. Most of the implementation is straightforward, but I’m stuck on writing the `deinit` method.

The struct looks like this:

```zig
pub fn RcPtr(comptime T: type) type {
    return extern struct {
        len: usize,
        ptr: *T,

        self_ptr: *RcPtr(T),
        root_ptr: *RcPtr(T),

        // Creating new reference = adding clone
        clones: ?*ArrayList(*RcPtr(T)),
    };
}

```

RcPtr.ptr could be a single item pointer (eg. `T = *u8`) — or something that can be cast to a multi item pointer (eg. `[]u8` or [\*]u8). Most of the implementation is straightforward, but I’m stuck on deinit. Deallocating the memory for RcPtr’s underlying value requires knowing whether to call `allocator.free`, if T is a multi-item pointer, or `allocator.destroy` if it’s a single item pointer.

My code looks like this:

```zig
pub fn deinit(comptime T: type, rc_ptr: RcPtr(T), allocator: Allocator) void {
    var clones = rc_ptr.root_ptr.*.clones.?.*;

    const ref_count = clones.items.len;
    std.log.debug("Refcount {d}", .{ref_count});
    if (ref_count > 0) {
        allocator.destroy(rc_ptr.self_ptr);
        return;
    }

    // No living refs, initialize self destruct sequence!
    const value_ptr = rc_ptr.ptr;

    if (isMultiItemPointer(value_ptr)) {
        // Multi item pointer
        allocator.free(value_ptr.*);
    } else {
        // Single item pointer
        allocator.destroy(value_ptr);
    }

    // This will destroy rc_ptr, since it's in clones, so it's invalid from here on out
    while (clones.popOrNull()) |c| {
        allocator.destroy(c);
    }
    clones.deinit();
}

```

How can I implement `isMultiItemPointer(value_ptr)`?

---

<div class="post-metadata">

**Author:** ![ForeverZer0](https://ziggit.dev/user_avatar/ziggit.dev/foreverzer0/32/2443_2.png) [@ForeverZer0](https://ziggit.dev/u/ForeverZer0)\
**Post date:** [January 3, 2025, 4:52am UTC](https://ziggit.dev/t/how-to-check-if-a-pointer-is-a-single-item-or-multi-item-pointer-to-determine-whether-to-call-free-or-destroy/7655/2 "2025-01-03T04:52:03Z")

</div>

Assuming by your example that the type is known at comptime, you can switch based on @typeInfo.

```zig
pub fn deinit(comptime T: type, rc_ptr: RcPtr(T), allocator: std.mem.Allocator) void {
    // do whatever other logic...

    switch (@typeInfo(T).Pointer.size) {
        .One => allocator.destroy(value_ptr),
        .Many => allocator.free(value_ptr),
        else => unreachable, // .Slice, .C
    }
}

```
