简体   繁体   English

如何在 Zig 中的堆上创建 HashMap?

[英]How can I create a HashMap on the heap in Zig?

The conventional way to make an object on the heap is to make a create fn:在堆上创建对象的常规方法是创建一个 create fn:

const Something = struct {
   a:Allocator,
   b:[1000]u8,
   pub fn create(a:Allocator) !*Something {
      var mem = try a.create(Something)
      mem.* = {
       .a =a,
       .b = undefined
      };
      return mem;
   }
}

But what about if I want to put a std lib ArrayHashMap on the heap?但是如果我想把一个标准库 ArrayHashMap 放在堆上呢? For example:例如:

const StringStringArrayHashMap = std.StringArrayHashMap([]const u8);

fn makeMap(a:Allocator) StringStringArrayHashMap {
   return StringStringArrayHashMap.init(a);
}

const WithMap = struct {
   map:StringStringHashMap
};

fn fillMap(a:Allocator) !WithMap {
   const map = makeMap(a);
   try map.put("a", "hello");
   try map.put("b", "world");
   return WithMap { .map = map };
}
fn badMemory(a:Allocator) !void {
   const with_map = fillMap(a);
   _ = with_map;
}

badMemory will receive a WithMap but it's internal map , having been made on the stack in fillMap will be freed at the end of fillMap and consequently unsade in badMemory . badMemory将收到一个WithMap但它是内部map ,在fillMap fillMap时释放,因此在badMemory中取消。

I can't see any way to make a valid HashMap without somehow hacking the internals of the zig stdlib.如果不以某种方式破解 zig stdlib 的内部结构,我看不出有什么方法可以制作有效的 HashMap。

You can put the map on the heap the same way you did with Something type:您可以像使用Something类型一样将地图放在堆上:

var map: *StringStringArrayHashMap = try allocator.create(StringStringArrayHashMap);
map.* = StringStringArrayHashMap.init(allocator);

badMemory will receive a WithMap but it's internal map , having been made on the stack in fillMap will be freed at the end of fillMap and consequently unsafe in badMemory . badMemory将收到一个WithMap但它是内部map ,在 fillMap 的堆栈上创建将在fillMap结束时被释放,因此在fillMapbadMemory

This is false.这是错误的。 The map is safe to use in badMemory as it's copied to the stack in badMemory .该映射在badMemory中使用是安全的,因为它已复制到badMemory中的堆栈。 (Or maybe the compiler could decide to pass it as a pointer, I'm not sure if parameter's pass-by-value rule applies to the return value. Doesn't matter here.) But you should probably be careful when copying the map or you might step into the same issue as this question . (或者编译器可能决定将其作为指针传递,我不确定参数的按值传递规则是否适用于返回值。这里无关紧要。)但是复制地图时您应该小心或者你可能会遇到与这个问题相同的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM