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析构器,则安全代码无法创建这类对象.
乍一看,需要一种方法告诉编译器"仅在隐式调用析构器时,是可信任的".

posted @   zjh6  阅读(10)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示