我今天看到了new
的使用,我不熟悉。
{
string * test = new string("bye");
new (test) string("hello");
cout << *test << endl; //prints "hello"
delete test;
}
一开始似乎应该这样,但如果我试着&#34;记得&#34; test
的初始值,看起来内存被重新分配:
string * test = new string("bye");
string * test2 = test;
new (test) string("hello");
cout << *test << endl; //prints "hello"
cout << *test2 << endl; //also prints "hello"
这里发生了什么?
答案 0 :(得分:2)
是的,你有( * )内存泄漏。不,检查代码没有另外说明。它表明你指向的两个指针都指向同一个对象。
要理解这一点,请注意std::string
通常将文本存储在其他位置,并在动态分配的缓冲区中。
因此,当您new
std::string
时,至少会有两个动态分配:
std::string
对象本身。内存泄漏是关于缓冲区的,因为没有运行第一个std::string
对象的析构函数,所以没有释放缓冲区。
* )“可能”而不是确定,因为与std::string
相比,std::vector
可以使用短缓冲区优化来存储数据直接
答案 1 :(得分:2)
确实存在潜在的内存泄漏,但不是因为你可能在想,有两个new
和一个delete
。这实际上很好。
问题是第一个字符串的析构函数永远不会运行。它所分配的任何内部存储器都不会被释放。
要解释,第二个new
是展示位置new
。它是一种在已经分配的内存上调用构造函数的方法。 (这是一个过于简单化的问题,但我们不要偏离。如果你想更多地了解展示位置new
,你就知道谷歌在哪里。) {{1是它用另一个字符串(new (test) string("hello")
)覆盖第一个字符串("bye"
)。展示位置"hello"
不会分配更多内存。它只在现有内存区域运行new
构造函数。
这就是程序打印string::string(const char *)
两次的原因。 hello
和test
都指向相同的字符串,因此当您覆盖该字符串时,更改会显示在两个变量中。变量本身没有改变,但他们指向的对象有。
答案 2 :(得分:1)
您正在查看的内容称为“新位置”。它在已经分配的内存块上调用构造函数。
由于原始对象从未被破坏,因此肯定会导致内存泄漏。如果它没有,可能是因为短字符串包含在对象本身内,并且不会导致字符串缓冲区的分配。