String 为字符串分配内存
在D字符串中是不可变的String 为字符串分配内存,string,d,String,D,在D字符串中是不可变的char[]上的别名。因此,字符串处理上的每个操作都需要分配内存。我想检查一下,但在替换字符串中的符号后,我看到了相同的地址 string str = "big"; writeln(&str); str.replace("i","a"); writeln(&str); 输出: > app.exe 19FE10 19FE10 我试过使用ptr: string str = "big"; writeln(str.ptr); str.replace(`i`
char[]
上的别名。因此,字符串处理上的每个操作都需要分配内存。我想检查一下,但在替换字符串中的符号后,我看到了相同的地址
string str = "big";
writeln(&str);
str.replace("i","a");
writeln(&str);
输出:
> app.exe
19FE10
19FE10
我试过使用ptr
:
string str = "big";
writeln(str.ptr);
str.replace(`i`,`a`);
writeln(str.ptr);
并得到下一个输出:
42E080
42E080
所以它显示的是同一个地址。为什么?在D中,所有数组都是长度+指向数组值开头的指针。它们通常存储在堆栈上,而堆栈恰好是RAM 当您获取一个变量的地址(位于函数体中)时,您真正要做的是获取指向堆栈的指针 要获取数组值的地址,请使用
.ptr
。
因此,将
&str
替换为str.ptr
,您将获得正确的输出。您在代码中犯了一个简单错误:
str.replace(“i”、“a”)
str.replace
返回替换完成后的新字符串,它实际上并不替换现有变量。所以试着用str=str.replace(“i”,“a”)代码>以查看更改
但你也对分配做了过于笼统的陈述:
因此,字符串处理上的每个操作都需要分配内存
这是错误的,很多操作都不需要分配新内存。任何可以对现有字符串进行切片的操作都可以这样做,从而避免需要新内存:
import std.string;
import std.stdio;
void main() {
string a = " foo ";
string b = a.strip();
assert(b == "foo"); // whitespace stripped off...
writeln(a.ptr);
writeln(b.ptr); // but notice how close those ptrs are
assert(b.ptr == a.ptr + 2); // yes, b is a slice of a
}
replace
如果实际没有进行替换,也将返回原始字符串:
string a = " foo ";
string b = a.replace("p", "a"); // there is no p to replace
assert(a.ptr is b.ptr); // so same string returned
索引和迭代不需要新的分配(当然)。信不信由你,但即使是追加有时也不会分配内存,因为在片的末尾可能还有未使用的内存(尽管通常会)
还有各种函数返回范围对象,这些对象在迭代时进行更改,从而避免分配。例如,代替替换(a,“f”和“”)代码>,您可以执行类似于过滤器的操作!(ch=>ch!='f')(a)编码>并循环,除非您要求,否则不会分配新字符串
所以这比你想象的要微妙得多 我已经测试过了,它显示的是相同的地址。这是我最后一个编辑主题,`string*str\u ptr;str_ptr=&str;写(str_ptr)`和` writeln(str.ptr)`&str
是指向数组的指针,str.ptr
是指向内容的指针。