这种新用法会造成内存泄漏吗?

时间:2014-10-02 01:59:21

标签: c++

我今天看到了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"

这里发生了什么?

3 个答案:

答案 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 *)两次的原因。 hellotest都指向相同的字符串,因此当您覆盖该字符串时,更改会显示在两个变量中。变量本身没有改变,但他们指向的对象有。

答案 2 :(得分:1)

您正在查看的内容称为“新位置”。它在已经分配的内存块上调用构造函数。

由于原始对象从未被破坏,因此肯定会导致内存泄漏。如果它没有,可能是因为短字符串包含在对象本身内,并且不会导致字符串缓冲区的分配。