d手动析构可能违反内存安全
析构器的目的是描述对象生命期结束时的清理工作.允许@safe代码在该点前手动调用析构器,然后继续用析构对象会破坏RAII内存管理:
module app;
import core.stdc.stdlib : malloc, free;
struct UniqueInt {
private int* target;
this(const(bool) doCreate) scope @trusted nothrow @nogc {
target = cast(int*) malloc(int.sizeof);
*target = 5;
}
@disable this(this);
@disable this(ref typeof(this));
@disable ref typeof(this) opAssign(ref typeof(this));
void withBorrow(void delegate(scope int*) @safe action) @safe {
action(target); }
~this() scope @trusted nothrow @nogc {
if(target !is null) {
free(target);
target = null;
}
}
}
//
UniqueInt unique;
shared static this() {
unique = true; }
void main() @safe {
import std.stdio: writeln;
unique.withBorrow((scope int* borrowed) @safe {
writeln(*borrowed);
destroy(unique);
writeln(*borrowed); // 释放后使用
});
}
我认为合理解决方案是:不管~this()属性如何,使调用__dtor,__xdtor或手动析构为@system操作.
为了在安全函数中自动创建T类型对象,T的析构器必须是安全的或受信任的.
目前析构器由__dtor成员函数体现,即析构器声明的属性与生成的__dtor成员函数的属性相同.
有些类型需要定义析构器来做不安全的事情,主要是释放对象内仔细限制的内存.
这产生了以下难题:
1.如果类型使析构器为@trusted,则表明安全代码也可自由地手动调用__dtor().后续用此类对象就会破坏安全.
2.如果类型选择用@system析构器,则安全代码无法创建这类对象.
乍一看,需要一种方法告诉编译器"仅在隐式调用析构器时,是可信任的".
浙公网安备 33010602011771号