1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Odin Odinlang Memo

Last updated at Posted at 2024-03-14

Allocator

トラッキングアロケーター
package main

import "core:mem"

// トラッキングアロケーター: メモリーリークを検出する
// コンパイル時に '-debug' を加えると ODIN_DEBUG が 'true' になる

main :: proc() {

	when ODIN_DEBUG {
		track: mem.Tracking_Allocator
		mem.tracking_allocator_init(&track, context.allocator)
		context.allocator = mem.tracking_allocator(&track)

		defer {
			if len(track.allocation_map) > 0 {
				fmt.eprintf("=== %v allocations not freed: ===\n", len(track.allocation_map))
				for _, entry in track.allocation_map {
					fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location)
				}
			}
			if len(track.bad_free_array) > 0 {
				fmt.eprintf("=== %v incorrect frees: ===\n", len(track.bad_free_array))
				for entry in track.bad_free_array {
					fmt.eprintf("- %p @ %v\n", entry.memory, entry.location)
				}
			}
			mem.tracking_allocator_destroy(&track)
		}
	}

	a := make([dynamic]int)
	append(&a, 0)
	defer delete(a) // コメントアウトするとメモリーリークが発生する

}
テンプアロケーター
package main

// テンプアロケーター: サイズが不足したらサイズが勝手に伸びるアリーナアロケーター
// a scratch allocator (a growing arena based allocator)

main :: proc() {

	context.allocator = context.temp_allocator
	defer free_all(context.temp_allocator)

}
ヒープを利用したアリーナアロケーター
package main

import "core:mem"

// ヒープを利用したアリーナアロケーター: ヒープ上にメモリーを置く + サイズは固定(伸縮不可)

main :: proc() {

	block_heap_memory := make([]byte, 2 * mem.Megabyte)
	assert(block_heap_memory != nil)
	defer delete(block_heap_memory)

	arena_heap: mem.Arena

	mem.arena_init(&arena_heap, block_heap_memory[:])

	heap_allocator := mem.arena_allocator(&arena_heap)

	context.allocator = heap_allocator
	defer free_all(heap_allocator)


	a := make([dynamic]int)
	append(&a, 1)

	assert(block_heap_memory[0] == 1)
}
スタックを利用したアリーナアロケーター
package main

import "core:mem"

// スタックを利用したアリーナアロケーター: メモリーをヒープ上に置くヒープベースのアロケーターのスタック版

main :: proc() {

	block_stack_buffer: [512]byte

	arena_stack: mem.Arena

	mem.arena_init(&arena_stack, block_stack_buffer[:])

	stack_allocator := mem.arena_allocator(&arena_stack)

	context.allocator = stack_allocator
	defer free_all(stack_allocator)

	a := make([dynamic]int)
	append(&a, 1)

	assert(block_stack_buffer[0] == 1)
}

Explicit/Implicit parametric polymorphism (parapoly)

proc
square :: proc($N: $T) -> (res: T) {
	res = N * N
	return
}

main :: proc() {
	{
		a := square(2)
		fmt.printf("%v %v\n", typeid_of(type_of(a)), a)
	}
	{
		a := square(2.3)
		fmt.printf("%v %v\n", typeid_of(type_of(a)), a)
	}
}

// int 4
// f64 5.289999999999999
struct
S :: struct($Key, $Value: typeid) {
	key:   Key,
	value: Value,
}

main :: proc() {
	{
		a := S(string, int){"foobar", 1}

		// a := S(string, int) {
		// 	key   = "foobar",
		// 	value = 1,
		// }

		// a: S(string, int)
		// a.key = "foobar"
		// a.value = 1

		fmt.printf("%v\n", a)
	}
}

// S($Key=string, $Value=int){key = "foobar", value = 1}
union
Error :: enum {
	Error1,
	Error2,
}

U :: union($T: typeid) {
	T,
	Error,
}

main :: proc() {

	{
		a: U(int)
		a = 1
		// or
		// a = .Error1

		fmt.printf("%v\n", a)
	}
}

// 1

Pointer

package main

import "core:fmt"
import "core:mem"

pointer1 :: proc() {
	ptr: ^int
	if ptr == nil do fmt.println("nil")
	var := 0
	fmt.println("var =", var)
	ptr = &var
	ptr^ = 9999
	fmt.println("var =", var)
}

pointer2 :: proc() {
	var := 0
	ptr := &var
	ptrptr := &ptr
	ptrptr^^ = 9999
	fmt.println("var =", var)
}

pointer3 :: proc() {
	arr := [?]int{1, 2, 3, 4, 5}
	ptr := &arr[0]
	fmt.println("arr[0] =", ptr^)
	fmt.println("arr[1] =", mem.ptr_offset(ptr, 1)^)
	fmt.println("arr[4] =", mem.ptr_offset(ptr, 4)^)
	// fmt.println("arr[5] =", mem.ptr_offset(ptr, 5)^) // out of range
}

pointer4 :: proc() {
	arr := [?]i32{1, 2, 3, 4, 5}
	start := &arr[0]
	end := &arr[4]
	fmt.println(start^, end^)
	fmt.println(&start, &end)
	fmt.println(mem.ptr_sub(start, end))
	fmt.println(mem.ptr_sub(end, start))
}

main :: proc() {

	fmt.println(">> Pointer 1")
	pointer1()
	fmt.println(">> Pointer 2")
	pointer2()
	fmt.println(">> Pointer 3")
	pointer3()
	fmt.println(">> Pointer 4")
	pointer4()

}

// >> Pointer 1
// nil
// var = 0
// var = 9999
// >> Pointer 2
// var = 9999
// >> Pointer 3
// arr[0] = 1
// arr[1] = 2
// arr[4] = 5
// >> Pointer 4
// 1 5
// 0x4A0CEFF598 0x4A0CEFF590
// -4
// 4
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?