d的分配器1
原文
D最近在内存安全的-preview=dip1000方面取得了很大进展,这九分要归功于Dennis Korpel的工作.这一进展反之又使AteEskola创建了有望在Phobos的下个版本中提供的SafeRefCounted这里.
下一步是支持std.experimental.allocator的SafeRefCounted版本.可惜,遇见问题了.
SafeRefCounted知道拥有有效负载的独针时,允许它@trusted的调用free,因为它(从C标准)知道此时调用free,不会破坏内存.
但是,调用通用Allocator.deassign函数,而不是free的分配器相关的SafeRefCount版本,不知道该函数将做什么,因此无法标记该调用为@trusted.
唯一方法是允许释放(通过扩展free的deallocate)有自己的@safe接口,这在当前的D语言中是不可能的.至少,它需要保证指针是指定内存块的独针的隔离限定符(这里).当然,所有权/借贷也可.
这不是可在库代码中解决的问题.必须更改语言.
好吧,阿提拉开始了它,所以他有点功劳.我在某个时候"偷"了他的pr.
它应可.要仔细定义释放器.如果释放器随后乱搞,则应该怪释放器,而不是SafeRefCounted.除非是故意内存泄漏器或GC,否则都无法@safe,因此用户必须编写错误的@trusted或@system代码,才能导致UB.
我同意,对思考如何改善@live的人,阅读孤立(isolated)的工作原理是值得的.
这是约定安全,正是@safe要摆脱的.可在示例代码和小型项目中工作,但它不能扩展,因为维护安全要求的工作量会随程序大小(与代码路径数成比例)呈指数级增长.
为此,需要编译器强制约束释放器.
为什么?释放器必然是@system.
表明是否启用分配器引用计数并不重要.总之,根据约定,释放器内部都是安全的,但假定正确编写释放器,由编译器在客户代码中确保安全.
如果有隔离(isolated),则可让释放器带隔离指针参数来使它@safe.
你是对的,仅让编译器在deallocer上约束是不够的,调用代码还必须知道约束规则.
长远看,此语言变化是理想的.然而,观点是,我们不能等待它.使用当前语言可启用分配器的安全引用计数器(也许有些漏洞).缺点是必须不仅审查释放器自己导致UB,还要避免泄漏指针来让@safe代码访问它.
好吧,当然,编写不合理的@trusted代码,总可@safe.😃
SafeRefCounted析构器不会像现在这样不健壮.如果free乱搞,析构器上的@trusted属性将无效.它与自定义释放器一样.
由C语言标准定义free的接口.原位(包括社会和技术)有很多适当保护措施,以避免不合理的释放(free)进入你的程序.
因此,对SafeRefCount的@trusted析构器来说,依赖符合C语言标准的free风险不大.
无此类保护措施的自定义释放器很可能会破坏内存安全.
因此,使用自定义释放器时,@safe代码中允许内存破坏的风险比使用free时要高得多.
:这样说,只有可证明没有其他别名时才可释放?
在@safe代码,这是释放内存的必要条件.仅当它不创建悬针时,才能这样.
:此时,不妨使用该证明,并让编译器为你释放.😉
不一定.证明依赖如引用计数等编译器不一定知道的运行时信息.此时,可转换指针为@trusted代码中的隔离(类似锁互斥锁后,丢弃@trusted代码中的共享(shared)).
浙公网安备 33010602011771号