Given two slices, is there a method in the standard library to check if they overlap (point to the same memory)?
Don’t think so, it would be in std.mem
and doesn’t appear to be.
Not especially difficult to write,
const a_start = slice_a.ptr;
const a_end = slice_a[slice_a.len..].ptr;
const b_start = slice_b.ptr;
const b_end = slice_b[slice_b.len..].ptr;
Then you cast them to usize
with @intFromPtr
and just check if either end is between the other pair.
Doesn’t this assume a “linear memory model”?
Is this a valid assumption?
8 posts were split to a new topic: Unified memory models and AddressSpace
I believe this is the relevant issue:
and this doesn’t appear to work:
const std = @import("std");
fn assertNonOverlapping(noalias slice1: []u8, noalias slice2: []u8) void {
_ = slice1;
_ = slice2;
}
test "check for overlaps" {
var buf = [3]u8{ 1, 2, 3 };
const second_slice: []u8 = buf[1..2];
assertNonOverlapping(&buf, second_slice);
}
No, it assumes something weaker: that valid memory in a process always has unique addresses.
If you think about it, every pointer in a slice must be valid, and unique. Nothing could possibly work if this wasn’t true. Valid means the number you have points to the address, unique means only that number (in your process) can point to that address.
A linear memory model would mean that there’s real actual addresses between pointer A and pointer B, and that’s not a safe assumption, each page is randomized but every page offset given to a process is unique. It has to be.
So what is safe is that if the ranges of the start and end pointer do not overlap, the memory doesn’t overlap, and if they do, it does.