what i'm looking for is a c style vla:
int len = 5;
int foo[len] = { 0 };
where len is mutable.
in odin this is invalid: Array count must be a constant integer, got len
len := 4
foo: [len]i32 = {}
achieving this is odin is possible
len := 4
arr_data: [^]i32 = cast([^]i32)(intrinsics.alloca(size_of(i32)*len, size_of(i32)))
arr_slice: []i32 = p[0:len];
but I feel like I'm missed something.
I can't find any reference to this outside of
arr: [dynamic]i32
arr.allocator = context.temp_allocator
but the stack allocators in the docs say that they're arenas, not stack allocators.
expected for this to just work
len := 4
foo: [len]i32 = {}
what i'm looking for is a c style vla:
int len = 5;
int foo[len] = { 0 };
where len is mutable.
in odin this is invalid: Array count must be a constant integer, got len
len := 4
foo: [len]i32 = {}
achieving this is odin is possible
len := 4
arr_data: [^]i32 = cast([^]i32)(intrinsics.alloca(size_of(i32)*len, size_of(i32)))
arr_slice: []i32 = p[0:len];
but I feel like I'm missed something.
I can't find any reference to this outside of
arr: [dynamic]i32
arr.allocator = context.temp_allocator
but the stack allocators in the docs say that they're arenas, not stack allocators.
expected for this to just work
len := 4
foo: [len]i32 = {}
Share
Improve this question
asked Feb 14 at 1:43
hacke2manhacke2man
112 bronze badges
1 Answer
Reset to default 0Variable Length Array in C can lead to stack overflow issues if the size becomes too large and that's why Odin doesn't have direct VLAs.
Using intrinsics.alloca
and pointer slicing is the closest you can get to a C-style VLA in Odin as it does allocate memory on the stack. However it has limited scope as you can see in its description in package base:intrinsics
A procedure that allocates size bytes of space in the stack frame of the caller, aligned to align bytes. This temporary space is automatically freed when the procedure that called
alloca
returns to its caller
The context.temp_allocator
is designed for temporary allocations within a specific scope (usually a function call).
The way to handle variable-sized arrays in Odin is to use slices and dynamic allocation with make
make
built-in procedure allocates and initializes a value of type slice, dynamic array, map, or multi-pointer (only).Similar to
new
, the first argument is a type, not a value. Unlike new, make's return type is the same as the type of its argument, not a pointer to it.Make
uses the specified allocator, default iscontext.allocator
.
Odin's memory management handles the deallocation of the heap-allocated array when it's no longer needed.
package main
import "core:fmt"
main :: proc() {
// Initial Allocation:
initial_size := 5
my_slice := make([]int, initial_size) // Allocate on the heap
// Initialization:
for i in 0 ..< initial_size {
my_slice[i] = i * 2
}
fmt.println("Initial slice:", my_slice)
fmt.println("Length of my_slice:", len(my_slice))
// Slicing
sub_slice := my_slice[2:5]
fmt.println("Sub-slice:", sub_slice)
// Modifying a slice affects the original
sub_slice[0] = 99
fmt.println("Sub-slice after modification:", sub_slice)
fmt.println("Original slice after sub-slice modification:", my_slice)
// Creating a new slice with different size
new_size := 3
another_slice := make([]string, new_size)
another_slice[0] = "Odin"
another_slice[1] = "is"
another_slice[2] = "cool"
fmt.println("Another slice:", another_slice)
// Passing a slice to a function
print_slice :: proc(s: []int) {
fmt.println("Slice inside function:", s)
for value in s {
fmt.println("Value:", value)
}
}
print_slice(my_slice)
}