3

这个问题可能是重复的。我一直在网上到处寻找以解决这个问题,但我找不到任何东西。“新”和“*新”有什么区别?:

int main()
{
    class Cat
    {
        //Code
    }

    new Cat();
    *new Cat();

    return 0;
}
4

3 回答 3

17

这不是两个独立的东西。没有 anew和 a *new。第二个是简单地将一元*应用于 的结果new Cat()

new Cat()是一个新表达式。它动态分配和初始化一个Cat对象,并计算出指向该对象的指针。如果然后将一元*应用于该指针,则取消引用它以获取Cat对象。

*立即将一元应用于new-expression的理由并不多。原因是您立即跟随指针并且没有将指针存储在任何地方。考虑一下你是否这样做了:

Cat c = *new Cat();

这将导致您无法恢复的内存泄漏。对象是动态分配的Cat,然后复制到c. 动态分配的Cat现在徘徊,你没有指向它的指针,你可以通过它来delete获取对象。这真是太糟了。

Cat& c = *new Cat();

这稍微好一点,因为至少现在c只是对动态分配对象的引用。您可以随时delete &c;销毁对象。Cat但是,它掩盖了动态分配的事实。如果我正在阅读这段代码,我不会期望c指的是动态分配的对象。

您必须记住销毁动态分配的对象。取消引用new-expression的结果会使它更难实现,所以要避免它。

于 2013-04-20T14:57:44.343 回答
12

这个表达式:

new Cat();

动态创建一个类型的对象Cat,并且您忽略返回的指针(不存储它,不取消引用,什么都没有)。这个表达式:

*new Cat();

与上述相同,只是您还取消引用由 . 返回的指针new。但是取消引用指针本身是一个没有副作用的操作。

因此,具体而言,这两种表达方式的效果是相同的。重要的一点是您通过丢失一个并且仅引用您动态创建的对象而泄漏内存两次。

请记住,使用创建的每个对象都new必须通过相应的调用来销毁delete。例如,如果您以这种方式存储返回的指针:

Cat* pCat = new Cat();

这将允许您稍后执行以下操作:

delete pCat;

并避免内存泄漏。另外,这个:

Cat& cat = *new Cat();

稍后将允许您执行以下操作:

delete &cat;

并避免再次发生内存泄漏。但是请注意,这不是一个选项:

Cat cat = *new Cat();

以上仍然会给你一个内存泄漏。原因是它会复制new通过取消引用into返回的指针获得的对象cat。换句话说,cat将是与new表达式创建的对象不同的对象(尽管相同)。

new另一方面,由表达式创建的对象将丢失 - 再次导致内存泄漏。

在现代 C++ 中,建议通过调用newand来避免手动内存管理delete;相反,请考虑使用智能指针(取决于您需要的所有权策略)。例如:

#include <memory>

// ...

std::shared_ptr<Cat> pCat = std::make_shared<Cat>();

当指向对象的最后一个智能指针被销毁时,智能指针会自动销毁被引用的对象。

于 2013-04-20T14:58:24.623 回答
6

对您有帮助吗:

Cat *ptr = new Cat();
Cat cat = *new Cat(); /* memory leak :( */
于 2013-04-20T14:59:07.357 回答