string s = "Hello world";
char* s2 = s.c_str();
将S2在栈上分配,或在人堆里?换句话说......我需要删除s2吗?
s2
在堆栈上,是的。但是,它是一个指向字符的指针(在这种情况下,恰好是在s
的文本内容的ASCIIZ表示中的第一个字符)。该文本本身就是s
对象觉得构建该表示的地方。不过,他们喜欢实现,但std::string
的关键实现选择是他们是否提供了“短字符串优化”,允许将非常短的字符串直接嵌入到s
对象中,以及“Hello world”是否足够短从该优化受益:
- 如果是这样,那么
s2
将指向堆内s
- 否则分配的内存,内部
s
会有一个指向空闲存储/堆分配的内存,其中的“Hello world \ 0“内容将会出现,其地址将由.c_str()
返回,并且s2将是该值的副本。
注意c_str()
是const
,所以你的代码编译,你需要改变const char* s2 = ...
。
您不需要删除s2,no。 s2分数据仍由s
对象拥有和管理的数据将由于s
的非const
方法或s
超出范围的任何调用而失效。
string s = new string("Hello, mr. heap...");
char* s2 = s.c_str();
现在的s2上堆,其起源是在堆上?
此代码不能编译,因为s
不是一个指针和一个字符串没有像string(std::string*)
构造。你可以将其更改为:
string* s = new string("Hello, mr. heap...");
......或者......
string s = *new string("Hello, mr. heap...");
后者创建了一个内存泄漏和没有用处,所以我们假设前者。然后:
char* s2 = s.c_str();
...需要成为...
char* s2 = s->c_str();
现在的s2上堆,其起源是在堆上?
是的。在所有的情况下,特别是如果s
本身在堆上,然后:
- 即使里面有
s
短串优化缓冲到c_str()
产生一个指针,它必须是在堆中,否则
- 如果
s
使用指向更多内存的指针来存储文本,则该内存也将从堆中分配。
但同样,即使知道了肯定s2
指向堆分配的内存,你的代码并不需要解除分配内存 - 它会自动完成时s
被删除:
string* s = new string("Hello, mr. heap...");
const char* s2 = s->c_str();
...use s2 for something...
delete s; // "destruct" s and deallocate the heap used for it...
中当然,通常使用string s("xyz");
更好,除非您需要超出本地范围的使用期限,否则使用std::unique_ptr<std::string>
或std::shared_ptr<std::string>
。
有趣,所以,你永远不会释放char *,因为这样做会释放字符串中的内部数据? c_str()字面上保持与字符串使用的实际数据相同的地址?多次调用.c_str()会以这种方式返回相同的地址? (只是澄清,所以我知道我明白) – 2012-01-12 23:03:51
@Georges这些问题的答案取决于你是否使用最新的标准或旧标准。你可能想澄清哪一个你感兴趣。 – 2012-01-12 23:05:45
@ R.MartinhoFernandes更好地使用最新的标准。这将是有趣的,但要知道这个标准是多么新近 – 2012-01-12 23:06:32