d如何实现动态栈分配数组
struct A {}
struct B { A a; }
struct C { A a; }
A*[] structs;
B b;
init(&b);
structs ~= cast(A*)&b;
错误:复制cast(A*)&b到分配内存中会逃逸b局部变量引用
C c;
init(&c);
structs ~= cast(A*)&c;
batch_process(structs);//最后
错误:复制cast(A*)&c到分配内存中会逃逸c局部变量引用
这样:cast(A*)&b.a?
如果确实想把对象放置在堆中.动态数组提供GC拥有的"内存".
以下程序交替把B和C放入缓冲区,然后批处理:
struct A { int i; }
struct B { A a; }
struct C { A a; }
A*[] structs;
void append(T, Args...)(ref ubyte[] structs, Args args) {
import std.conv : emplace;
structs.length += sizeWithPadding!T;
auto where = cast(T*)(&structs[$ - sizeWithPadding!T]);
emplace(where, args);
}
void main() {
ubyte[] structs;
foreach (i; 0 .. 10) {
if (i % 2) {
structs.append!B(A(i));
} else {
structs.append!C(A(i));
}
}
batch_process(structs);
}
auto process(T)(const(ubyte)[] structs) {
import std.stdio : writeln;
writeln(*cast(T*)structs.ptr);
return structs[sizeWithPadding!T..$];
}
void batch_process(const(ubyte)[] structs) {
import std.range : empty;
for (size_t i = 0; !structs.empty; i++) {
if (i % 2) {
structs = structs.process!B();
} else {
structs = structs.process!C();
}
}
}
T * nextAlignedAddress(T)(T * candidateAddr) {
import std.traits;
static if (is (T == class)) {
const alignment = classInstanceAlignment!T;
} else {
const alignment = T.alignof;
}
const result = (cast(size_t)candidateAddr + alignment - 1)
/ alignment * alignment;
return cast(T*)result;
}
void * nextAlignedAddress(T)(void * candidateAddr) {
return nextAlignedAddress(cast(T*)candidateAddr);
}
size_t sizeWithPadding(T)() {
static if (is (T == class)) {
const candidateAddr = __traits(classInstanceSize, T);
} else {
const candidateAddr = T.sizeof;
}
return cast(size_t)nextAlignedAddress(cast(T*)candidateAddr);
}
从这里复制了nextAlignedAddress和sizeWithPadding函数.
我知道,垃集分配动态数组且禁止在垃集内存中保存局部变量引用,但是这里假设structs不会逃逸,可用固定大小数组实现:
A*[32] structs;
int i = 0;
structs[i++] = cast(A*)&b;
但是我想知道是否有具有最大容量限制可像普通动态数组一样连接的栈分配数组.
类似:
assumeNoEscapeOrWhatever!
DynamicArray structs;
structs ~= cast(A*)&b;
这就是@trusted的目的.也是为什么应小心使用它,并尽量最小化代码.
struct A {}
struct B { A a; }
struct C { A a; }
void main()
{
A*[] structs;
B b;
C c;
() @trusted {
structs ~= cast(A*)&b;
structs ~= cast(A*)&c;
} ();
}
这是我要的,但为何
void func() @trusted
{
A*[] structs;
B b;
structs ~= cast(A*)&b; // 仍然错误
}
不工作呢?
浙公网安备 33010602011771号