d静态数组生存期
如下代码非期望:
int[] foo()
{
int[1024] static_array;
// return static_array[];
//返回`'static_array[]'`时逃逸了局部变量`'static_array'`的引用
return null;
}
class A
{
this(int[] inData)
{
data = inData;
}
int[] data;
}
void main()
{
int[] arr;
A a;
{
int[1024] static_array;
arr = aSlice; // OK
a = new A(aSlice); // OK
arr = foo();
//arr = foo();
}
}
通过赋值aSlice
给arr
或a
,它似乎逃逸
了域,我以为会
有错误,但代码编译
得很好.
真的安全
吗?
切片是原数组
拥有的现有内存
的视图
.切片不会分配
内存.GC
跟踪动态数组
,分配
的内存的所有引用
,因此只要切片
活跃,则原内存
也活跃.
在栈
上分配静态数组
,它们离开函数域
时就失效
了.同样,引用栈内存
的切片或其他指针
也是如此.
这里重要的不是域
,而是栈
.内部域
中分配的内存使用函数栈
,因此在退出
函数前,所有内存
都是有效的.
不,它不安全.可在程序头加@安全:
行,(在重命名static_array
为aSlice
后),它无法编译:
test.d(27)
:错误:赋值'aSlice'
变量的地址给具有较长生命期的'arr'
.
默认,假定所有内容都为@system
.
退出域
时,会调用析构器
,等等.
谢谢,@safe
对第一片代码管用,但是下面
代码仍然可编译:
class A
{
@safe
this(int[] inData)
{
data = inData;
}
int[] data;
}
@safe
int[] foo()
{
int[1024] static_array;
//返回`'static_array[]'`时逃逸了局部变量`'static_array'`的引用
return null;
}//.1
@safe
A bar()
{
int[1024] static_array;
return new A(static_array[]);
}//.2
@safe
void main()
{
auto a = bar();
writeln(a.data); // OK, 但写的是垃圾
}
所以编译器在foo()
中检测逃逸
,而在bar()
中没有,这不对.
是否可区分
切片是来自动态
数组还是静态
数组?
编译器
可用-dip1000
开关来检测它.
为了调试
?也许找到栈边界
,检查地址
是否在栈中?
.1
对编译器
来说是很简单的.
.2
需要更深层次
分析代码.是的,传递了切片
给构造器
,但是不知道构造器
是否会存储
该切片,或只是使用
它.即使下面代码
是安全的,但编译器不能检测
:
class A
{
@safe
this(int[] inData)
{
data = someCondition() ? new int[42] : inData; // (1)
// ...
if (someOtherCondition()) {
data = null; // (2)
}
}
// ...
}
(1)
根据someCondition()
,确定是否使用inData
,可能根据程序中的someCondition()
,根本不会调用bar()
.
(2)
构造器退出后,根据someOtherCondition()
,数据可能不会引用"static_array"
编译器很难看穿.(@live
也许有帮助.)此外,"单独编译
"使它看不穿函数边界
.
此外,不希望编译器强制复制
所有栈变量
.
D的安全模型
一样.在@安全
代码中,D
拒绝编译器不确定内存安全
的内容.然而,与Rust
中不同的是,@安全
在D中不是默认
的,因此要手动标记.
@safe``删除
破坏内存.@live
正在通过跟踪
数据活跃度来改善.
@安全
的目标是确保在@安全
代码中不能破坏
内存,仅在@系统
或@信任
中间断出现,如果文档没说不清楚,就是文档的问题.
但是,存在一些需要重大更改
才能@安全
的已知
的问题,并且为了使现有
代码更易迁移
,这些更改
隐藏在dip1000
下,因此实践中,如果不带-dip1000
的使用@安全
,可能会遇见危及内存安全
的编译器错误
.
你的示例,就是这样
.不带-dip1000
,应禁止@安全
代码中切片栈分配的静态数组
,但由于存在漏洞
,编译器允许它,因此应由-dip1000
开关修复该错误
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现