浏览代码

Fix make and reserve

- Set the allocator, even if memory allocation fails.
  Right now it doesn't, which means that if allocation fails, it'll use
  the context allocator instead. This memory will be leaked if the user
  doesn't understand that this happened.

- Only set len and cap of the array returned from make iif the memory allocation
  succeeded.
  This means that reserve will return false if you do this:
  ```
  a := make([dynamic]int, failing_allocator);
  if !reserve(&a, 5) do return; // or whatever indicates failure
  ```
Tetralux 5 年之前
父节点
当前提交
b32ef9e47b
共有 2 个文件被更改,包括 6 次插入2 次删除
  1. 3 1
      core/mem/alloc.odin
  2. 3 1
      core/runtime/core.odin

+ 3 - 1
core/mem/alloc.odin

@@ -124,8 +124,10 @@ make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, auto_cast len: int, alloc
 make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, auto_cast len: int, auto_cast cap: int, allocator := context.allocator, loc := #caller_location) -> T {
 	runtime.make_dynamic_array_error_loc(loc, len, cap);
 	data := alloc(size_of(E)*cap, align_of(E), allocator, loc);
-	if data == nil do return nil;
 	s := Raw_Dynamic_Array{data, len, cap, allocator};
+	if data == nil {
+		s.len, s.cap = 0, 0;
+	}
 	return transmute(T)s;
 }
 make_map :: proc($T: typeid/map[$K]$E, auto_cast cap: int = 16, allocator := context.allocator, loc := #caller_location) -> T {

+ 3 - 1
core/runtime/core.odin

@@ -628,8 +628,10 @@ make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, auto_cast len: int, alloc
 make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, auto_cast len: int, auto_cast cap: int, allocator := context.allocator, loc := #caller_location) -> T {
 	make_dynamic_array_error_loc(loc, len, cap);
 	data := mem_alloc(size_of(E)*cap, align_of(E), allocator, loc);
-	if data == nil do return nil;
 	s := Raw_Dynamic_Array{data, len, cap, allocator};
+	if data == nil {
+		s.len, s.cap = 0, 0;
+	}
 	return transmute(T)s;
 }