为什么使用“new”会导致内存泄漏? [英] Why does the use of 'new' cause memory leaks?

查看:638
本文介绍了为什么使用“new”会导致内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我先学C#,现在我从C ++开始。据我所知,C ++中的操作符 new 与C#中的不一样。



这个示例代码中的内存泄漏?

  class A {...} 
struct B {...};

A * object1 = new A();
B object2 = *(new B());


解决方案

发生了什么 / p>

当你写 T t; 你正在创建一个类型 T 使用自动存储持续时间



当你写 new T()使用动态存储持续时间重新创建 T 类型的对象。它不会自动清除。





您需要传递一个指向 delete 的指针, p>



但是,你的第二个例子是更糟的:你解引用指针,并创建一个对象的副本。这样,您将失去指向使用 new 创建的对象的指针,因此即使您想要也不能删除它!





什么您应该



您应该更喜欢自动存储时间。需要一个新对象,只需写:

  A a; // A new object of type A 
B b; //类型B的新对象

如果您需要动态存储持续时间,

 模板< typename T> 
class automatic_pointer {
public:
automatic_pointer(T * pointer):pointer(pointer){}

//析构函数:清理时调用
//在这种情况下,我们要使用delete
〜automatic_pointer(){delete pointer; }

//模拟指针!
//用这个我们可以写* p
T& operator *()const {return * pointer; }
//这样我们可以写p> f()
T * operator->()const {return pointer; }

private:
T * pointer;

//对于这个例子,我只是禁止复制
//一个更聪明的类可以处理这个方法
automatic_pointer(automatic_pointer const&);
automatic_pointer& operator =(automatic_pointer const&);
};

automatic_pointer< A> a(new A()); //行为像一个指针,但自动删除
automatic_pointer< B> b(new B()); //行为像一个指针,但自动删除



这是一个常见的成语,由非常描述性的名称RAII 资源获取正在初始化)。当您获取需要清理的资源时,您将其置于自动存储持续时间的对象中,因此您不必担心清理它。



这个 automatic_pointer 事情已经以各种形式存在,我刚刚提供它给一个例子。在标准库中名为 std :: unique_ptr 的非常类似的类。



-C ++ 11)命名为 auto_ptr ,但现在已弃用,因为它有一个奇怪的复制行为。



还有一些甚至更聪明的例子,如 std :: shared_ptr ,允许多个指针到同一个对象,只有当最后一个指针被销毁时清理它。


I learned C# first, and now I'm starting with C++. As I understand, operator new in C++ is not similar to the one in C#.

Can you explain the reason of the memory leak in this sample code?

class A { ... };
struct B { ... };

A *object1 = new A();
B object2 = *(new B());

解决方案

What is happening

When you write T t; you're creating an object of type T with automatic storage duration. It will get cleaned up automatically when it goes out of scope.

When you write new T() you're creating an object of type T with dynamic storage duration. It won't get cleaned up automatically.

You need to pass a pointer to it to delete in order to clean it up:

However, your second example is worse: you're dereferencing the pointer, and making a copy of the object. This way you lose the pointer to the object created with new, so you can never delete it even if you wanted!

What you should do

You should prefer automatic storage duration. Need a new object, just write:

A a; // a new object of type A
B b; // a new object of type B

If you do need dynamic storage duration, store the pointer to the allocated object in an automatic storage duration object that deletes it automatically.

template <typename T>
class automatic_pointer {
public:
    automatic_pointer(T* pointer) : pointer(pointer) {}

    // destructor: gets called upon cleanup
    // in this case, we want to use delete
    ~automatic_pointer() { delete pointer; }

    // emulate pointers!
    // with this we can write *p
    T& operator*() const { return *pointer; }
    // and with this we can write p->f()
    T* operator->() const { return pointer; }

private:
    T* pointer;

    // for this example, I'll just forbid copies
    // a smarter class could deal with this some other way
    automatic_pointer(automatic_pointer const&);
    automatic_pointer& operator=(automatic_pointer const&);
};

automatic_pointer<A> a(new A()); // acts like a pointer, but deletes automatically
automatic_pointer<B> b(new B()); // acts like a pointer, but deletes automatically

This is a common idiom that goes by the not-very-descriptive name RAII (Resource Acquisition Is Initialization). When you acquire a resource that needs cleanup, you stick it in an object of automatic storage duration so you don't need to worry about cleaning it up. This applies to any resource, be it memory, open files, network connections, or whatever you fancy.

This automatic_pointer thing already exists in various forms, I've just provided it to give an example. A very similar class exists in the standard library called std::unique_ptr.

There's also an old one (pre-C++11) named auto_ptr but it's now deprecated because it has a strange copying behaviour.

And then there are some even smarter examples, like std::shared_ptr, that allows multiple pointers to the same object and only cleans it up when the last pointer is destroyed.

这篇关于为什么使用“new”会导致内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆