#I just can't even array
1 messages · Page 1 of 1 (latest)
I think I am just going to go
cards: [128]*Instance,
and call it a day, because then I can just sort that since it's the same as an array of usize anyway
again, what are you trying to do here? sorting some cards and sorting them?
(const sort = (&[_]usize{ 1, 0 })[0..]; this will produce a value for you.)
imminent dangling pointer
i'm not saying you should 😄 I'm saying that this will produce something
I can't get that to compile either
to draw them I need to be able to change the sort order and that's all, so I can just sort a slice of the fixed size array of pointers instead
Taking the address of a intermediate/temporary value gives a constant pointer, so []const T. Which slice are you trying to "sort"?
OP needs to think about the memory layout:
[]usizethis says you want a pointer to mutable memory
so there are two problems with the following line:.sort = ([_]usize{ 1, 0 })[0..]
first of all, when you create a value like[_]usize{ 1, 0 }and don't specify it to bevar, it isconstby default, so if you take a slice it will be const memory, not mutable memory.
You could do something similar to milk's suggestion:
var arr = [_]usize{ 1, 0 };
.sort = &arr
but where do you think the memory is located? I'm honestly not sure myself; either it's a local in your function, in which case you're returning a dangling pointer because the local gets destroyed once you return, or you're returning a pointer to a global, in which case you get duplicate pointers if you initialise with this function multiple times.
You have to use heap memory allocation if you want to work with slices safely here.
made a mistake, gonna correct it....
My point is that you need to have a plan for where your memory is when you're using pointers. So maybe it's wise to just use a fixed size array while you're still trying to figure things out, maybe as a temporary solution.
I am trying to avoid cloning things, so Instance has a field that is a pointer to the Card struct, which will have exactly one instance of every unique Card living on the heap. (Instance has some other fields for game state modifiers too)
then Hand is just a collection of Instances
the size can probably be constrained to something small, given uncertain final rules, but I will just allocate it fixed size and large to start
thanks all, I think this was a good sanity check, I was expecting some more elegant solution but I think the very nature of Zig is the explicit allocation of memory, and if a dynamic sized array is needed, then there are ways to go about handling that, but it's probably overkill when the overall amount of memory usage is small and not that variable
it would be exactly the same as
fn f() *usize {
var res: usize = 0;
return &res;
}
and you definitely don't need heap allocation. stack is very much fine, it doesn't matter where it is. what matters is that it outlives the scope, which means it just must be within the scope of the caller, which means it cannot be inside the callee.
To OP:
first of all, consider if you could not represent your Instance as an enum or a number or a bitset. consider if it needs to be a pointer.
you can represent a state of an entire deck of cards with 52 bits
(unless it's not the regular card deck. but even if it's not regular cards, do think about it.)
second of all, if we don't consider that, let me see if I understand you correctly.
you have a bunch of things on the heap and you wish to have a buffer where all of them are sorted according to some property. right?
and you're asking about how / where to have that buffer / how to make it, right?
yeah I guess that's the crux of the question -- where/how to declare that buffer
if you do know the upper bound of things, then you can definitely preallocate it
I can very easily envision some similar programming later where I am dealing with an Inventory containing unique Items (not pointers) with many fields/values, and wanting dynamic sizing
ok, so to do that, you need to allocate a bunch of memory. you can do that either on the stack, or use some heap-allocator.
let's do in on the stack, because it's the most simple, and it seems you're already trying to do that by making an array. which is exactly what you would do if you want to stack-allocate, and this is how you do it:
var buf: [N]T = undefined;
var user: User = .{ .buf = &buf };
now user refers to the block of memory that buf is (which can hold N number of T things). now user can use it however it fits.
the undefined means that there are currently no defined values in the entire block buf.
we do that when we will be using it to write to it. reading from it would be illegal, as long as it's undefined.
if you know the upper bound, but the actual memory used is variable, then you can have
var buf: [N]T = undefined;
var user: User = .{ .buf = &buf, .count = 0 };
where count is the number of things actually used in the buffer. you could then get it like
const items = user.buf[0..user.count];
am I on the right track for you?
yes, that is actually very helpful, both in terms of knowing how to do it, and knowing it actually is the right approach
glad to hear!