#Creating fixed size matrix at runtime

1 messages · Page 1 of 1 (latest)

heady crown
#

i'd like to simply be able to do matrix[y][x] = ... instead if using an arraylist where i have to attempt

pine gale
#

you could allocate slices for each row

#

and a slice of slices would be the matrix itself

heady crown
pine gale
#

and then the matrix would be allocator.alloc([]f32, matrix_height);

#

youd probably wanna make the matrix, then loop through it and allocate each row and fill it

heady crown
pine gale
heady crown
#

will it make the struct for each cell

#

or one struct for all

pine gale
#

itll be whatever data type T you want in each cell, i used f32 here just as an example, i dont know what you mean by one struct for all

heady crown
#

i might instead use ?Cell

pine gale
#

i think thatll work? and itll be the same data copied into each cell

#

no reason to use ?Cell if theyre never going to be null after you init them

#

if memset doesnt work you can just do for (m) |c| c.* = Cell { … };

heady crown
#

ah m.*

pine gale
#

yep 👍

heady crown
#

i tested it

for (mat) |m| for (m) |*r| {
        try stdout.print("matrix {}\n", .{&r});
    };
#

and every cell points to the same place in memory

#

i want the opposite

#

so i assume i need a for loop?

pine gale
#

try removing the & in front of the r

pine gale
heady crown
#

why is &r the same for every eiteration

heady crown
#

im curious now tho, how do i get the address of the element?

pine gale
#

you already do, r is a pointer to each element

#

and if you print r it prints the address the pointer is holding

heady crown
#
for (mat) |m| for (m) |*r| {
        try stdout.print("matrix {}\n", .{r});
    };

this prints out the element not the address:(

pine gale
#

oh it worked with f32's for me but if it's a struct you need {*}

heady crown
#

ah yeah that fixed it

#

cool thanks

pine gale
#

np 👍

cloud cliff
# pine gale ```rs var matrix = try allocator.alloc([]f32, matrix_height); for (matrix) |*m| ...

If you do this, I'd do more this instead:

const matrix = try allocator.alloc([]f32, matrix_height);
const elems = try allocator.alloc(f32, matrix_height * row_width);
var i: usize = 0; 
for (matrix) |*m| {
    m.* = elems[i..][0..row_width];
    i += row_width;
}

You could even compute the number of bytes needed ahead of time, and do this instead:

const cell_count = matrix_height * row_width;
const total_bytes_needed = (cell_count * @sizeOf(f32)) + (matrix_height * @sizeOf([]f32));
const backing = try allocator.alignedAlloc(u8, @alignOf([]f32), total_bytes_needed);
const fba_state = std.heap.FixedBufferAllocator.init(backing);
const fba = fba.allocator();

const matrix = try fba.alloc([]f32, matrix_height);
const elems = try fba.alloc(f32, cell_count);
var i: usize = 0; 
for (matrix) |*m| {
    m.* = elems[i..][0..row_width];
    i += row_width;
}

This way, you only need allocator.free(backing);, rather than this for the first example:

allocator.free(elems);
allocator.free(matrix);
pine gale
heady crown
#

the first one tho

#

i dont really get that one

cloud cliff
#

Makes the allocation pattern simpler, and both easier and quicker to free it.

#

The second one simply takes this one step further by putting the elements and the column-slice into one allocation, rather than just the elements.

cloud cliff