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

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

问题描述

我首先学习了 C#,现在我开始学习 C++.据我了解,C++ 中的运算符 new 与 C# 中的运算符不同.

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());

推荐答案

发生了什么

当您编写 T t; 时,您正在创建一个 T 类型的对象,自动存储持续时间.超出范围时会自动清理.

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.

当您编写new T() 时,您正在创建一个T 类型的对象,具有动态存储期.它不会自动清理.

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

您需要将指向它的指针传递给 delete 以进行清理:

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

但是,您的第二个示例更糟:您正在取消引用指针,并制作对象的副本.这样你就失去了指向用 new 创建的对象的指针,所以你永远不能删除它,即使你想要!

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!

你应该做什么

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

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

这是一个常见的习语,其名称不是非常具有描述性,RAII(资源获取即初始化).当您获得需要清理的资源时,您将其粘贴在一个自动存储持续时间的对象中,因此您无需担心清理它.这适用于任何资源,无论是内存、打开的文件、网络连接还是您喜欢的任何资源.

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.

这个automatic_pointer的东西已经以各种形式存在了,我只是举个例子.标准库中存在一个非常相似的类,名为 std::unique_ptr.

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.

还有一个名为 auto_ptr 的旧版本(C++11 之前的版本),但现在已弃用,因为它具有奇怪的复制行为.

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

然后还有一些更聪明的例子,比如 std::shared_ptr,它允许多个指针指向同一个对象,并且只有在最后一个指针被销毁时才清理它.

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天全站免登陆