d动态数组容量
string str = "0123456789ABCDEF";
char[] chr = str.dup;
assert(str.length == 16);
assert(str.capacity == 0);
import std.math: thus = nextPow2; //.algebraic
assert(chr.capacity == thus(str.length) - 1);
assert(chr.capacity == 31);
动态数组,按2的指数增长分配,而串不一样?
另外,.ptr保存最近的第一个元素地址,对吗?
write("str[0]@", &str[0]);
writeln(" == @", str.ptr);
write("chr[0]@", &chr[0]);
writeln(" == @", chr.ptr);
你已用串字面初化了str.GC不这样为他们分配内存.它们存储在二进制文件中,操作系统从磁盘加载他们到内存中.所以str.ptr指向固定大小静态内存位置,因此无额外容量.
chr使用(可改变的)运行时算法从GC分配.更具体地说,指向已分配内存块的起始地址.
给定T[]类型的ts实例,访问数组本质如下:
ts[0] == *(ts.ptr + 0);
ts[1] == *(ts.ptr + 1);
ts[2] == *(ts.ptr + 2);
由于T的大小是已知的,因此每次加指针都会增加N*T.sizeof字节.如果转换为ubyte数组,则需要自己处理.同样,&ts[0]==&(*ts.ptr + 0)==ts.ptr==&(*(ts.ptr+0)).
容量是,追加时无需重新分配的可存储多少个数组元素.
为什么串字面是0?因为它不从GC分配,因此没有附加的容量(请注意,即使串当前有16个字符,也会返回0容量).
为什么垃集分配的数组是31?这是实现细节:
GC按2的指数(大部分)分配,最小块为16字节,下个大小为32字节.
为了记住用了哪个块,要分配空间来记录它.对16字节的块,需要1个字节.因而31,还有1字节用于记录.
串是,长度加指针而已.str.ptr是串第一个元素的指针.没有"最近的第一个元素"的概念.
import std.range;
import std.stdio;
/* 切换数组
alias chr = char*;
auto data = [' '];/*/
alias chr = immutable(char*);
auto data = " ";//*/
void main()
{
chr[] ptrs;
data.fill(3, ptrs);
writeln;
foreach(ref ptr; ptrs)
{
" 0x".write(ptr);
}
} /* 打印:
0: 0 1: 15 2: 31 3: 47
0x55B07E227020 0x7F2391F9F000 0x7F2391FA0000 0x7F2391FA1000
//*/
void fill(R)(ref R mostRecent, int limit, ref chr[] ptrs)
{
auto ptr = mostRecent.ptr;
size_t capacity, depth;
while (depth <= limit)
{
mostRecent ~= ElementType!R.init;
if(ptr != mostRecent.ptr)
{
ptrs ~= ptr;
depth.writef!"%2s: %11s"(capacity);
depth++;
}
if (mostRecent.capacity != capacity)
{
ptr = mostRecent.ptr;
capacity = mostRecent.capacity;
}
}
}
浙公网安备 33010602011771号