GPA allocator returns the same address multiple times?

In this example, I’m filling a buffer with 100 allocations of type u8 from the gpa allocator and then storing them into the buffer. When I run a basic comparison operation over them, several of the slice pointers are comparing as equal. When I write print them out, here’s what the result is:

ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (16, 36)
ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (16, 51)
ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (16, 65)
ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (16, 76)
ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (36, 51)
ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (36, 65)
ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (36, 76)
ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (51, 65)
ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (51, 76)
ptr i: u8@ffffffffffffffff, ptr j: u8@ffffffffffffffff, (65, 76)

Now, you’ll notice that I am using a PCG random int generator seeded at 42. When this seed is changed to 66 for me, this problem goes away.

Here’s the example code:

pub fn main() !void  
{   
    const GPA = @import("std").heap.GeneralPurposeAllocator(.{});
    const rand = @import("std").rand;
    const Buffer = @import("std").ArrayList;
    const print = @import("std").debug.print;
    
    var gpa = GPA{};
    var allocator = gpa.allocator();
    var buffer = Buffer([]u8).init(allocator);
    var PCG = rand.Pcg.init(42);
    var pcg = PCG.random();


    defer {
        for(buffer.items) |data| {
            allocator.free(data);        
        }   
        buffer.deinit();   
        if (gpa.deinit() == .leak) { 
            @panic("LEAK DETECTED"); 
        }
    }
    
    for(0..100) |_| {
        var n = pcg.int(usize);
        n = if(n == 0) 1 else n % 100;
        try buffer.append(try allocator.alloc(u8, n));
    }

    var i: usize = 0;
    while(i < (buffer.items.len - 1)) : (i += 1) {

        var j: usize = i + 1;
        while(j < buffer.items.len) : (j += 1) {
            if(buffer.items[i].ptr == buffer.items[j].ptr) {
                print("\nptr i: {any}, ptr j: {any}, ({any}, {any})", .{
                    buffer.items[i].ptr,
                    buffer.items[j].ptr,        
                    i,
                    j
                });  
            }
        }    
    }
}

Anyhow, this is causing the ptrA == ptrB to return true sporadically and I’m not sure if this intended behaviour? I can’t imagine why if it is.

I think I see what’s up. I have my mod written wrong and I think they get set to usize max, hence @ffff

So pointers don’t get assigned to an undefined number by default. That’s just my C background talking here.

n = if(n == 0) 1 else n % 100; can evaluate to 0 if n % 100 == 0

alloc with a len of 0 is a special case that doesn’t allocate and returns a pointer with the value maxInt(usize):

1 Like

Yeah, lol… I just realized that. Thanks for pitching in though!

1 Like