以下所有内容都是朴素的编译器所能做的。当然,只要它不改变程序的行为,编译器可以自由地进行任何优化。
string a;
a = "hello!";
首先你初始化一个包含空字符串。 (将长度设置为0,以及一两个其他操作)。然后,您分配一个新值,覆盖已设置的长度值。它可能还必须执行检查以查看当前缓冲区有多大,以及是否应分配更多内存。
string *a;
a = new string("hello!");
...
delete(a);
调用new需要操作系统和内存分配器来查找空闲的内存块。这很慢。然后你立即初始化它,所以你不会分配任何东西两次或者需要缓冲区的大小,就像你在第一个版本中一样。 然后发生了一些不好的事情,并且你忘记了调用delete,并且你有一个内存泄漏,另外给一个分配非常慢的字符串。所以这是不好的。
string a;
a = "less";
a = "moreeeeeee";
就像第一种情况一样,首先初始化a以包含空字符串。然后你分配一个新的字符串,然后另一个。这些中的每一个都可能需要来调用new来分配更多的内存。每一行也需要长度,并可能分配其他内部变量。
通常情况下,你分配这样的:
string a = "hello";
一号线,一旦执行初始化,而不是第一个默认初始化,然后指定你想要的值。
它还最大限度地减少了错误,因为您的程序中没有任何空缺的空字符串。如果字符串存在,它包含您想要的值。
关于内存管理,google RAII。 简而言之,字符串在内部调用new/delete来调整其缓冲区大小。这意味着你永远不会需要分配一个新的字符串。字符串对象具有固定的大小,并被设计为在堆栈上分配,以便在超出作用域时自动调用。析构函数保证任何分配的内存都被释放。这样,您不必在用户代码中使用新的/删除,这意味着您不会泄漏内存。
你使用的是特定的字符串类,还是只是标准的以null结束的cstrings? – tsellon 2009-02-10 20:20:41
我会假设问题是关于std :: string。 – rmeador 2009-02-10 20:23:34