string - How does std.string.toStringz work in dlang?
问题描述
https://dlang.org/library/std/string/to_stringz.html
In my understanding it could not work:
toStringz
creates an array on the stack and returns its pointer. After toStringz
returns, the array on the stack is discarded and the pointer becomes invalid.
But I suppose it indeed works because of being a part of the standard library. So what is wrong in my understanding of the above?
Another related question:
What does scope return
in the signature of this function mean? I visited https://dlang.org/spec/function.html but found no scope return
there.
解决方案
它不会在堆栈上创建数组。如有必要,它会在 GC 堆上分配一个新字符串。
该实现通过检查现有字符串的零终止符来工作 - 如果它认为可以在没有内存故障的情况下这样做(这是通过检查最后一个字节的对齐方式来猜测。如果它是四的倍数,它不会冒险,但如果不是,它会在指针之前读取一个字节,因为故障边界位于四个间隔的倍数上)。
如果那里已经有一个零字节,它会返回未修改的输入。这就是return
签名中的意思——它可能会返回相同的输入。(这是一个刚刚记录的新功能......昨天。它甚至还没有合并:https ://github.com/dlang/dlang.org/pull/2536但是stdlib文档是从master重建的分支大声笑)
无论如何,如果那里没有零字节,它会分配一个新的 GC'd 字符串,复制现有的字符串,附加零,然后返回它。这就是为什么文档中的注释警告 C 函数保留它的原因。如果 C 函数让它无法执行,那么获取它的不是堆栈 - 它是 D 垃圾收集器。D 的 GC 看不到 C 函数分配的内存(除非特别通知它),并且会认为该字符串在下次运行时未被引用并因此释放它,从而导致释放后使用错误。
签名中的scope
关键字是 D 检查此 btw 的方式:这意味着参数将仅在此函数的范围内使用(尽管组合return
意味着它将仅在此函数的范围内使用或通过此函数返回)。但这是 toStringz 的输入 - 您调用的 C 函数可能不使用 D 语言限制,因此它不会被自动捕获。
所以再次总结属性:
scope
- 参数不会离开函数的范围。不会分配给全局或外部结构等。
return
- 参数可能由函数返回。
return scope
- 上述的混合体;它不会通过返回值离开函数的范围。
推荐阅读
- cryptography - 在 python 3.6 中使用 pycryptodome 或密码学。如何做到这一点?
- java - ANTLR 语法返回可以使用 java 编译器执行的 java 方法名称
- c# - 未找到使用 dotnet Core Web MVC 应用的 Azure AD 身份验证的质询和身份验证方案
- reactjs - 在 React SSR 上使用 redux-thunk 操作必须是普通对象错误
- python - 在 for 循环中计算“Digram”又名核苷酸对
- go - 我可以从嵌套模板访问顶级模板变量吗?
- python - 想要为 sprite pygame 添加一条线索
- java - 为什么 jvm 命令 `jinfo` 在 alpine openjdk8 发行版中没有`-flags`?
- python - 盒子宽度翻倍
- git - 从覆盖分支上未提交文件的 master 恢复合并