I’m glad you’re making progress - I’d like to take a step back and look at the fundamentals here.
deinit calls free on the underlying memory in the array list:
/// Release all allocated memory.
pub fn deinit(self: Self) void {
if (@sizeOf(T) > 0) {
self.allocator.free(self.allocatedSlice());
}
}
And we can see here what allocatedSlice does:
/// Returns a slice of all the items plus the extra capacity, whose memory
/// contents are `undefined`.
pub fn allocatedSlice(self: Self) Slice {
// `items.len` is the length, not the capacity.
return self.items.ptr[0..self.capacity];
}
In summary, deinit calls free on the full underlying slice - not just the part of it that is currently used by the array list. It essentially frees everything that the array list is currently hanging onto.
Okay, so what does toOwnedSlice() do? Here’s the code and then we’ll do the breakdown:
/// Its capacity is cleared, making deinit() safe but unnecessary to call.
pub fn toOwnedSlice(self: *Self, allocator: Allocator) Allocator.Error!Slice {
const old_memory = self.allocatedSlice();
if (allocator.resize(old_memory, self.items.len)) {
const result = self.items;
self.* = .{};
return result;
}
const new_memory = try allocator.alignedAlloc(T, alignment, self.items.len);
@memcpy(new_memory, self.items);
@memset(self.items, undefined);
self.clearAndFree(allocator);
return new_memory;
}
Basically, the first if statement says “we don’t need all this extra capacity, we only need what is actually used by the array list.” To accomplish this, they shrink it down to the self.items.len (which is smaller than or equal to self.capacity).
In the second case, they allocate only what they need and return the slice to you that is properly sized and free the older one that had extra capacity.
Okay, what does this have to do with ownership? toOwnedSlice ejects the memory from the array list to an “owning” slice. You now own that slice and the array list forgets about it (so if you call deinit on that array list, the array list is like “what memory?” because it’s been evacuated).
I hope that helps ![]()