std.string.toStringz如何在dlang中工作?

时间:2018-12-30 10:54:18

标签: string memory-management d interfacing

https://dlang.org/library/std/string/to_stringz.html

以我的理解,它不起作用:

toStringz在堆栈上创建一个数组并返回其指针。 toStringz返回后,堆栈上的数组将被丢弃并且指针变为无效。

但是我想它确实是有效的,因为它是标准库的一部分。那么我对上述情况的理解是什么错?

另一个相关问题:

此函数签名中的scope return是什么意思?我访问了https://dlang.org/spec/function.html,但那里没有scope return

1 个答案:

答案 0 :(得分:2)

它不会在堆栈上创建数组。如有必要,它将在GC堆上分配一个新字符串。

该实现通过检查现有字符串中的零终止符来工作-如果它认为有可能在没有内存错误的情况下这样做(可以通过检查最后一个字节的对齐来猜测。如果它是四的倍数,则为不会冒这个风险,但是如果不是这样,它会在指针之前读取一个字节,因为故障边界是四个间隔的倍数。

如果已经有一个零字节,它将返回未修改的输入。这就是签名中return的含义-它可能会返回相同的输入。 (这是一个新功能,昨天才被记录。。它甚至还没有被合并:https://github.com/dlang/dlang.org/pull/2536但是stdlib文档是从master分支大声笑中重建的)

无论如何,如果那里没有零字节,它将分配一个新的GC字符串,将现有的字符串复制过来,附加零,然后返回。这就是为什么文档中的注释会警告C函数保留它。如果C函数将其保留到执行之外,那么获取它的不是堆栈,而是D垃圾收集器。 D的GC无法看到C函数分配的内存(除非特别告知它),并且会认为该字符串在下次运行时未被引用,因此将其释放,从而导致释放后使用的错误。

签名中的scope关键字是D检查此btw的方式:这意味着该参数仅在该函数的作用域中使用(尽管return的组合意味着仅在以下情况下使用该参数)此函数的作用域或通过此函数返回)。但这是在toStringz的输入上的-您调用的C函数可能未使用D语言限制,因此不会被自动捕获。

因此,再次对属性进行总结:

scope-参数不会离开函数的范围。不会分配给全局或外部结构等。

return-函数可能返回该参数。

return scope-以上内容的混合体;它不会通过返回值离开函数的作用域。