最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

In odin is there a good way to make a variable length array on the stack - Stack Overflow

programmeradmin3浏览0评论

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
Add a comment  | 

1 Answer 1

Reset to default 0

Variable 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 is context.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)
}
发布评论

评论列表(0)

  1. 暂无评论