为什么要删除[]?

时间:2022-09-13 02:08:21

Lets say I have a function like this:

假设我有一个这样的函数:

int main()
{
    char* str = new char[10];

    for(int i=0;i<5;i++)
    {
        //Do stuff with str
    }

    delete[] str;
    return 0;
}
  1. Why would I need to delete str if I am going to end the program anyways? I wouldn't care if that memory goes to a land full of unicorns if I am just going to exit, right?

    如果我要终止程序,为什么还要删除str ?如果我要离开的话,我不会在意那些记忆会不会进入一片满是独角兽的土地,对吧?

  2. Is it just good practice?

    这只是一个好的练习吗?

  3. Does it have deeper consequences?

    它有更深层次的后果吗?

15 个解决方案

#1


74  

If in fact your question really is "I have this trivial program, is it OK that I don't free a few bytes before it exits?" the answer is yes, that's fine. On any modern operating system that's going to be just fine. And the program is trivial; it's not like you're going to be putting it into a pacemaker or running the braking systems of a Toyota Camry with this thing. If the only customer is you then the only person you can possibly impact by being sloppy is you.

如果你的问题真的是“我有这个小程序,在它退出之前我不释放几个字节可以吗?”任何现代操作系统都可以。这个程序很简单;这并不是说你要把它放进起搏器或者用丰田凯美瑞的刹车系统。如果唯一的客户是你,那么你唯一可以通过草率行事影响的人就是你。

The problem then comes in when you start to generalize to non-trivial cases from the answer to this question asked about a trivial case.

当你开始从这个问题的答案中归纳到非平凡的情况时,问题就出现了。

So let's instead ask two questions about some non-trivial cases.

让我们来问两个关于非平凡情况的问题。

I have a long-running service that allocates and deallocates memory in complex ways, perhaps involving multiple allocators hitting multiple heaps. Shutting down my service in the normal mode is a complicated and time-consuming process that involves ensuring that external state -- files, databases, etc -- are consistently shut down. Should I ensure that every byte of memory that I allocated is deallocated before I shut down?

我有一个长期运行的服务,它以复杂的方式分配和释放内存,可能涉及多个分配程序命中多个堆。在正常模式下关闭我的服务是一个复杂且耗时的过程,需要确保始终关闭外部状态(文件、数据库等)。我是否应该确保我分配的每一个字节的内存在我关闭之前被释放?

Yes, and I'll tell you why. One of the worst things that can happen to a long-running service is if it accidentally leaks memory. Even tiny leaks can add up to huge leaks over time. A standard technique for finding and fixing memory leaks is to instrument the allocation heaps so that at shutdown time they log all the resources that were ever allocated without being freed. Unless you like chasing down a lot of false positives and spending a lot of time in the debugger, always free your memory even if doing so is not strictly speaking necessary.

是的,我会告诉你为什么。对于长时间运行的服务来说,最糟糕的事情之一是它不小心泄漏了内存。随着时间的推移,即使是微小的泄漏也会累积成巨大的泄漏。查找和修复内存泄漏的标准技术是检测分配堆,以便在关机时记录所有已分配的资源,而不被释放。除非您喜欢追踪大量的误报,并在调试器中花费大量时间,否则始终要释放您的内存,即使这样做严格来说是没有必要的。

The user is already expecting that shutting the service down might take billions of nanoseconds so who cares if you cause a little extra pressure on the virtual allocator making sure that everything is cleaned up? This is just the price you pay for big complicated software. And it's not like you're shutting down the service all the time, so again, who cares if its a few milliseconds slower than it could be?

用户已经预料到关闭服务可能需要数十亿纳秒,所以谁会在意如果您对虚拟分配器造成一点额外的压力,以确保所有东西都已清理干净呢?这只是你为大型复杂软件付出的代价。这并不是说你一直在关闭服务,所以,谁会在意它是否比可能的慢了几毫秒呢?

I have that same long-running service. If I detect that one of my internal data structures is corrupt I wish to "fail fast". The program is in an undefined state, it is likely running with elevated privileges, and I am going to assume that if I detect corrupted state, it is because my service is actively being attacked by hostile parties. The safest thing to do is to shut down the service immediately. I would rather allow the attackers to deny service to the clients than to risk the service staying up and compromising my users' data further. In this emergency shutdown scenario should I make sure that every byte of memory I allocated is freed?

我有相同的长时间运行的服务。如果我发现我的一个内部数据结构是腐败的,我希望“快速失败”。程序处于未定义的状态,它可能运行时具有更高的特权,我将假设,如果我检测到已损坏的状态,那是因为我的服务正受到敌对方的主动攻击。最安全的做法是立即关闭服务。我宁愿让攻击者拒绝为客户提供服务,也不愿冒险让服务继续运行并进一步损害我的用户数据。在这个紧急关闭场景中,我是否应该确保分配的每个字节的内存都被释放?

Of course not. The operating system is going to take care of that for you. If your heap is corrupt, the attackers may be hoping that you free memory as part of their exploit. Every millisecond counts. And why would you bother polishing the doorknobs and mopping the kitchen before you drop a tactical nuke on the building?

当然不是。操作系统会帮你解决这个问题。如果您的堆损坏了,攻击者可能希望您将内存释放作为其攻击的一部分。几毫秒的时间。还有,你为什么要费心去擦门把手和拖厨房呢?

So the answer to the question "should I free memory before my program exits?" is "it depends on what your program does".

所以问题的答案是“我应该在程序退出之前释放内存吗?”

#2


39  

Yes it is good practice. You should NEVER assume that your OS will take care of your memory deallocation, if you get into this habit, it will screw you later on.

是的,这是很好的练习。你不应该假设你的操作系统会处理你的内存释放,如果你养成了这个习惯,它以后会把你搞砸。

To answer your question, however, upon exiting from the main, the OS frees all memory held by that process, so that includes any threads that you may have spawned or variables allocated. The OS will take care of freeing up that memory for others to use.

但是,要回答您的问题,在从主进程退出时,操作系统释放该进程持有的所有内存,以便包括您可能已经生成的任何线程或已分配的变量。操作系统将负责释放这些内存,供其他人使用。

#3


24  

Important note : delete's freeing of memory is almost just a side-effect. The important thing it does is to destruct the object. With RAII designs, this could mean anything from closing files, freeing OS handles, terminating threads, or deleting temporary files.

重要提示:delete释放内存几乎只是一个副作用。它所做的重要的事情是破坏对象。使用RAII设计,这意味着可以关闭文件、释放操作系统句柄、终止线程或删除临时文件。

Some of these actions would be handled by the OS automatically when your process exits, but not all.

当您的进程退出时,操作系统将自动处理其中的一些操作,但不是全部。

In your example, there's no reason NOT to call delete. but there's no reason to call new either, so you can sidestep the issue this way.

在您的示例中,没有理由不调用delete。但是也没有理由叫new,所以你可以用这种方式回避这个问题。

char str[10];

Or, you can sidestep the delete (and the exception safety issues involved) by using smart pointers...

或者,您可以通过使用智能指针来避免删除(以及涉及到的异常安全问题)……

So, generally you should always be making sure your object's lifetime is properly managed.

因此,通常您应该始终确保正确地管理对象的生命周期。

But it's not always easy: Workarounds for the static initialization order fiasco often mean that you have no choice but to rely on the OS cleaning up a handful of singleton-type objects for you.

但它并不总是那么简单:静态初始化顺序失败的工作区通常意味着您别无选择,只能依赖操作系统为您清理少量的singleton类型的对象。

#4


16  

Contrary answer: No, it is a waste of time. A program with a vast amount of allocated data would have to touch nearly every page in order to return all of the allocations to the free list. This wastes CPU time, creates memory pressure for uninteresting data, and possibly even causes the process to swap pages back in from disk. Simply exiting releases all of the memory back to the OS without any further action.

相反的回答:不,这是浪费时间。一个拥有大量已分配数据的程序几乎要访问每个页面才能将所有的分配返回到*列表中。这将浪费CPU时间,为无趣的数据创建内存压力,甚至可能导致进程从磁盘交换回页面。简单地退出将所有内存释放回操作系统,而不需要任何进一步的操作。

(not that I disagree with the reasons in "Yes", I just think there are arguments both ways)

(并不是说我不同意“是”的理由,我只是认为两种理由都有)

#5


6  

Your Operating System should take care of the memory and clean it up when you exit your program, but it is in general good practice to free up any memory you have reserved. I think personally it is best to get into the correct mindset of doing so, as while you are doing simple programs, you are most likely doing so to learn.

您的操作系统应该负责内存,并在退出程序时清理它,但通常来说,释放您所保留的任何内存都是很好的实践。我个人认为最好进入正确的心态去做,因为当你在做简单的程序时,你最有可能这样做是为了学习。

Either way, the only way to guaranteed that the memory is freed up is by doing so yourself.

无论哪种方式,确保释放内存的唯一方法就是自己这么做。

#6


4  

new and delete are reserved keyword brothers. They should cooperate with each other through a code block or through the parent object's lifecyle. Whenever the younger brother commits a fault (new), the older brother will want to to clean (delete) it up. Then the mother (your program) will be happy and proud of them.

new和delete是保留的关键字兄弟。它们应该通过代码块或父对象的生命周期相互协作。每当弟弟犯了一个错误(新的),哥哥就会想要清理(删除)它。然后母亲(你的程序)会为他们感到高兴和自豪。

#7


3  

I cannot agree more to Eric Lippert's excellent advice:

我完全同意给Eric Lippert的精彩建议:

So the answer to the question "should I free memory before my program exits?" is "it depends on what your program does".

所以问题的答案是“我应该在程序退出之前释放内存吗?”

Other answers here have provided arguments for and against both, but the real crux of the matter is what your program does. Consider a more non-trivial example wherein the type instance being dynamically allocated is an custom class and the class destructor performs some actions which produces side effect. In such a situation the argument of memory leaks or not is trivial the more important problem is that failing to call delete on such a class instance will result in Undefined behavior.

这里的其他答案为这两者提供了支持和反对的理由,但问题的真正关键是你的程序做了什么。考虑一个更重要的例子,其中被动态分配的类型实例是一个自定义类,而类析构函数执行一些产生副作用的操作。在这种情况下,内存泄漏的参数是无关紧要的,更重要的问题是,如果不调用此类类实例上的delete,将导致未定义的行为。

[basic.life] 3.8 Object lifetime
Para 4:

(基本。3.8对象生存期第4段:

A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

程序可以通过重用对象占用的存储或显式地为具有非平凡析构函数的类类型的对象调用析构函数来结束任何对象的生命周期。对于具有非平凡析构函数的类类型的对象,在对象占用的存储被重用或释放之前,程序不需要显式地调用析构函数;但是,如果没有显式调用析构函数,或者不使用delete-expression(5.3.5)来释放存储,则不应隐式地调用析构函数,任何依赖析构函数产生的副作用的程序都有未定义的行为。

So the answer to your question is as Eric says "depends on what your program does"

所以你的问题的答案正如Eric所说"取决于你的程序做什么"

#8


2  

It's a fair question, and there are a few things to consider when answering:

这是一个很公平的问题,在回答的时候要考虑以下几点:

  • some objects have more complex destructors which don't just release memory when they're deleted. They may have other side effects, which you don't want to skip.
  • 有些对象具有更复杂的析构函数,它们不仅在被删除时释放内存。他们可能有其他副作用,你不想跳过。
  • It is not guaranteed by the C++ standard that your memory will be released when the process terminates. (Of course on a modern OS it will be freed, but if you were on some weird OS which didn't do that, you'd have to free your memory properly
  • c++标准没有保证在进程终止时释放内存。(当然,在现代操作系统上,它会被释放,但是如果你在一些奇怪的操作系统上没有这样做,你必须正确地释放你的内存
  • on the other hand, running destructors at program exit can actually take up quite a lot of time, and if all the do is release memory (which would be released anyway), then yes, it makes a lot of sense to just short-circuit that and exit immediately instead.
  • 另一方面,在程序退出时运行析构函数实际上会占用很多时间,如果所有的操作都是释放内存(无论如何都会释放内存),那么是的,将其短路并立即退出是很有意义的。

#9


2  

Most operating systems will reclaim memory upon process exit. Exceptions may include certain RTOS's, old mobile devices etc.

大多数操作系统将在进程退出时回收内存。例外可能包括某些RTOS,旧的移动设备等。

In an absolute sense your app won't leak memory; however it's good practice to clean up memory you allocate even if you know it won't cause a real leak. This issue is leaks are much, much harder to fix than not having them to begin with. Let's say you decide that you want to move the functionality in your main() to another function. You'll may end up with a real leak.

在绝对意义上,你的应用程序不会泄漏内存;然而,即使你知道你分配的内存不会造成真正的泄漏,也要清理内存。这个问题是,要修复漏洞比一开始就不修复要难得多。假设您决定要将main()中的功能移动到另一个函数。你可能最终会有一个真正的漏洞。

It's also bad aesthetics, many developers will look at the unfreed 'str' and feel slight nausea :(

这也是不好的美学,许多开发人员将看到未释放的“str”,并感到轻微的恶心:

#10


2  

Why would I need to delete str if I am going to end the program anyways?

如果我要结束这个程序,为什么还要删除str ?

Because you don't want to be lazy ...

因为你不想偷懒……

I wouldn't care if that memory goes to a land full of unicorns if I am just going to exit, right?

如果我要离开的话,我不会在意那些记忆会不会进入一片满是独角兽的土地,对吧?

Nope, I don't care about the land of unicorns either. The Land of Arwen is a different matter, Then we could cut their horns off and put them to good use(I've heard its a good aphrodisiac).

不,我也不在乎独角兽的土地。亚玟的土地是不同的事情,然后我们可以砍下他们的角,好好利用他们(我听说这是一个好的春药)。

Is it just good practice?

这只是一个好的练习吗?

It is justly a good practice.

这是一种很好的做法。

Does it have deeper consequences?

它有更深层次的后果吗?

Someone else has to clean up after you. Maybe you like that, I moved out from under my parents' roof many years ago.

别人得替你收拾残局。也许你喜欢,我几年前从父母家搬出来的。

Place a while(1) loop construct around your code without delete. The code-complexity does not matter. Memory leaks are related to process time.

在代码周围放置一个while(1)循环结构,不删除。代码复杂性并不重要。内存泄漏与进程时间有关。

From the perspective of debug, not releasing system resources(file handles, etc) can cause more significant and hard to find bugs. Memory-leaks while important are typically much easier to diagnose(why can't I write to this file?). Bad style will become more of a problem if you start working with threads.

从调试的角度来看,不释放系统资源(文件句柄等)会导致更大的影响,并且很难发现bug。重要的内存泄漏通常更容易诊断(为什么我不能写入这个文件?)如果您开始使用线程,那么不良的样式将成为更大的问题。

int main()
{

    while(1)
    { 
        char* str = new char[10];

        for(int i=0;i<5;i++)
        {
            //Do stuff with str
        }
    }

    delete[] str;
    return 0;
}

#11


2  

Another reason that I haven't see mentioned yet is to keep the output of static and dynamic analyzer tools (e.g. valgrind or Coverity) cleaner and quieter. Clean output with zero memory leaks or zero reported issues means that when a new one pops up it is easier to detect and fix.

我还没有提到的另一个原因是,保持静态和动态分析工具(例如:valgrind或Coverity)的输出更干净、更安静。使用零内存泄漏或零报告问题清理输出意味着,当出现新的问题时,更容易检测和修复。

You never know how your simple example will be used or evolved. Its better to start as clean and crisp as possible.

你永远不知道你的简单例子将如何被使用或演变。越干净越好,越脆越好。

#12


2  

Not to mention that if you are going to apply for a job as a C++ programmer there is a very good chance that you won't get past the interview because of the missing delete. First - programmers don't like any leaks usually (and the guy at the interview will be surely one of them) and second - most companies (all I worked in at least) have the "no-leak" policy. Generally, the software you write is supposed to run for quite a while, creating and destroying objects on the go. In such an environment leaks can lead to disasters...

更不用说,如果你要申请一个c++程序员的工作,你很有可能会因为删除而错过面试。首先,程序员通常不喜欢任何泄漏(面试的那个人肯定是他们中的一员),其次,大多数公司(至少是我工作过的公司)都有“无泄漏”政策。通常,您编写的软件应该运行一段时间,在运行过程中创建和销毁对象。在这种环境下,泄漏会导致灾难……

#13


2  

You got a lot of professional experience answers. Here I'm telling a naive but an answer I considered as the fact.

你有很多专业经验的答案。我说的是一个幼稚但我认为是事实的答案。

  • Summary

    总结

    3. Does it have deeper consequences?

    3所示。它有更深层次的后果吗?

    A: Will answer in some detail.

    答:我会详细回答。

    2. Is it just good practice?

    2。这只是一个好的练习吗?

    A: It is considered a good practice. Release resources/memory you've retrieved when you're sure about it no longer used.

    A:这被认为是一个很好的做法。释放您已经检索到的资源/内存,当您确定它不再被使用时。

    1. Why would I need to delete str if I am going to end the program anyways?
      I wouldn't care if that memory goes to a land full of unicorns if I am just going to exit, right?
    2. 如果我要终止程序,为什么还要删除str ?如果我要离开的话,我不会在意那些记忆会不会进入一片满是独角兽的土地,对吧?

    A: You need or need not, in fact, you tell why. There're some explanation follows.

    A:你需要或者不需要,事实上,你知道为什么。有一些解释。

    I think it depends. Here are some assumed questions; the term program may mean either an application or a function.

    我认为这取决于。这里有一些假设的问题;“程序”一词可能指应用程序或函数。

    Q: Does it depend on what the program does?

    问:这取决于程序做什么吗?

    A: If universe destroyed was acceptable, then no. However, the program might not work correctly as expected, and even be a program that doesn't complete what it supposed to. You might want to seriously think about why you build a program like this?

    A:如果宇宙毁灭是可以接受的,那就没有。然而,程序可能不能正常工作,甚至是一个不能完成它应该完成的任务的程序。您可能想认真地思考为什么要构建这样的程序?

    Q: Does it depend on how the program is complicated?

    问:这取决于程序的复杂性吗?

    A: No. See Explanation.

    答:不是。看到的解释。

    Q: Does it depend on what the stability of the program is expected?

    问:这取决于程序的稳定性吗?

    A: Closely.

    密切。

    And I consider it depends on

    我认为这取决于

    1. What's the universe of the program?
    2. 程序的宇宙是什么?
    3. How's the expectation of the program that it done its work?
    4. 对这个项目的期望是什么?
    5. How much does the program care about others, and the universe where it is?

      这个程序对别人有多关心,对宇宙有多关心?

      About the term universe, see Explanation.

      关于“宇宙”一词,请参阅解释。

    For summary, it depends on what do you care about.

    总之,这取决于你关心什么。


  • Explanation

    解释

    Important: If we define the term program as a function, then its universe is application. There are many details omitted; as an idea for understanding, it's long enough, though.

    重要提示:如果我们将程序定义为函数,那么它的范围就是应用。省略了许多细节;作为一个理解的想法,它已经足够长了。

    We may ever seen this kind of diagram which illustrates the relationship between application software and system software.

    我们可能见过这种图表,它说明了应用软件和系统软件之间的关系。

    为什么要删除[]?

    But for being aware the scope of which one covers, I'd suggest a reversed layout. Since we are talking about software only, the hardware layer is omitted in following diagram.

    但是为了了解其中涉及的范围,我建议采用相反的布局。由于我们只讨论软件,因此在下面的图中省略了硬件层。

    为什么要删除[]?

    With this diagram, we realize that the OS covers the biggest scope, which is current the universe, sometimes we say the environment. You may imagine that the whole achitecture consists of a lot of disks like the diagram, to be either a cylinder or torus(a ball is fine but difficult to imagine). Here I should mention that the outmost of OS is in fact a unibody, the runtime may be either single or multiple by different implemention.

    通过这张图,我们认识到操作系统覆盖了最大的范围,即当前的宇宙,有时我们说环境。你可以想象整个猜想是由很多圆盘组成的,比如图,要么是圆柱体,要么是环面(球很好,但很难想象)。这里我要指出的是,大多数操作系统实际上是一个单主体,运行时可以是单个的,也可以是多个,由不同的实现实现。

    It's important that the runtime is responsible to both OS and applications, but the latter is more critical. Runtime is the universe of applications, if it's destroyed all applications run under it are gone.

    运行时同时负责操作系统和应用程序是很重要的,但后者更为重要。运行时是应用程序的宇宙,如果它被破坏了,那么它下面运行的所有应用程序都消失了。

    Unlike human on the Earth, we live here, but we don't consist of Earth; we will still live in other suitable environment if the time when the Earth are destroying and we weren't there.

    与地球上的人类不同,我们生活在这里,但我们不是由地球组成的;如果地球正在毁灭,而我们不在那里,我们仍将生活在其他适宜的环境中。

    However, we can no longer exist when the universe is destroyed, because we are not only live in the universe, but also consist of the universe.

    然而,当宇宙被毁灭时,我们就不复存在了,因为我们不仅生活在宇宙中,而且还包括宇宙。

    As mentioned above, the runtime is also responsible to the OS. The left circle in the following diagram is what it may looks like.

    如上所述,运行时还负责操作系统。下图中的左圆是它的样子。

    为什么要删除[]?

    This is mostly like a C program in the OS. When the relationship between an application and OS match this, is just the same situation as runtime in the OS above. In this diagram, the OS is the universe of applications. The reason of the applications here should be responsible to the OS, is that OS might not virtualize the code of them, or allowed to be crashed. If OS are always prevent they to do so, then it's self-responsible, no matter what applications do. But think about the drivers, it's one of the scenarios that OS must allowed to be crashed, since this kind of applications are treated as part of OS.

    这在操作系统中很像一个C程序。当应用程序和操作系统之间的关系匹配时,与上面操作系统中的运行时相同。在这个图中,操作系统是应用程序的宇宙。这里的应用程序应该对OS负责,因为OS可能不会虚拟化它们的代码,或者允许崩溃。如果操作系统总是阻止他们这样做,那么不管应用程序做什么,它都是自负责的。但考虑到驱动程序,这是OS必须允许崩溃的场景之一,因为这类应用程序被视为OS的一部分。

    Finally, let's see the right circle in the diagram above. In this case, the application itself be the universe. Sometimes, we call this kind of application operating system. If an OS never allowed custom code to be loaded and run, then it does all the things itself. Even it allowed, after itself is terminated, the memory goes nowhere but hardware. All the deallocation that may be necessary, is before it was terminated.

    最后,让我们看看上图中正确的圆。在这种情况下,应用程序本身就是整个宇宙。有时,我们称这种应用为操作系统。如果一个操作系统不允许自定义代码被加载和运行,那么它会自己做所有的事情。即使它允许,在它本身被终止之后,内存也只能是硬件。所有可能需要的释放都是在终止之前完成的。

    So, how much does your program care about the others? How much does it care about its universe? And how's the expectation of the program that it done its work? It depends on what do you care about.

    那么,您的程序在多大程度上关心其他程序呢?它有多关心它的宇宙?程序的期望是什么呢?这取决于你关心什么。

#14


2  

TECHNICALLY, a programmer shouldn't rely on the OS to do any thing. The OS isn't required to reclaim lost memory in this fashion.

从技术上讲,程序员不应该依赖操作系统做任何事情。操作系统不需要以这种方式恢复丢失的内存。

If you do write the code that deletes all your dynamically allocated memory, then you are future proofing the code and letting others use it in a larger project.

如果您确实编写了删除所有动态分配内存的代码,那么您就是在将来验证代码,并让其他人在更大的项目中使用它。

Source: Allocation and GC Myths(PostScript alert!)

来源:分配和GC神话(PostScript alert!)

Allocation Myth 4: Non-garbage-collected programs should always
deallocate all memory they allocate.

The Truth: Omitted deallocations in frequently executed code cause
growing leaks. They are rarely acceptable. but Programs that retain
most allocated memory until program exit often perform better without
any intervening deallocation. Malloc is much easier to implement if
there is no free.

In most cases, deallocating memory just before program exit is
pointless. The OS will reclaim it anyway. Free will touch and page in
the dead objects; the OS won't.

Consequence: Be careful with "leak detectors" that count allocations.
Some "leaks" are good!
  • I think it's a very poor practice to use malloc/new without calling free/delete.

    我认为使用malloc/new而不调用free/delete是非常糟糕的做法。

  • If the memory's going to get reclaimed anyway, what harm can there be from explicitly deallocating when you need to?

    如果内存无论如何都会被回收,那么在需要时显式地释放内存又有什么害处呢?

  • Maybe if the OS "reclaims" memory faster than free does then you'll see increased performance; this technique won't help you with any program that must remain running for any long period of time.

    也许如果操作系统“回收”内存的速度比免费快,那么您将看到性能的提高;这种技术对任何必须长时间运行的程序都没有帮助。

Having said that, so I'd recommend you use free/delete.

说到这里,我建议您使用free/delete。


If you get into this habit, who's to say that you won't one day accidentally apply this approach somewhere it matters?

如果你养成了这个习惯,谁又能说你不会有一天不小心把这个习惯应用到重要的地方呢?


One should always deallocate resources after one is done with them, be it file handles/memory/mutexs. By having that habit, one will not make that sort of mistake when building servers. Some servers are expected to run 24x7. In those cases, any leak of any sort means that your server will eventually run out of that resource and hang/crash in some way. A short utility program, ya a leak isn't that bad. Any server, any leak is death. Do yourself a favor. Clean up after yourself. It's a good habit.

在处理完资源之后,应该总是重新分配资源,无论是文件句柄/内存/互斥对象。有了这个习惯,在构建服务器时就不会犯这样的错误了。一些服务器预计运行24x7。在这些情况下,任何类型的泄漏都意味着您的服务器最终将耗尽该资源并以某种方式挂起/崩溃。一个简短的实用程序,对,泄漏不是那么糟糕。任何服务器,任何泄漏都是死亡。帮自己一个忙。收拾自己。这是一个好习惯。


Think about your class 'A' having to deconstruct. If you don't call
'delete' on 'a', that destructor won't get called. Usually, that won't
really matter if the process ends anyway. But what if the destructor
has to release e.g. objects in a database? Flush a cache to a logfile?
Write a memory cache back to disk? **You see, it's not just 'good
practice' to delete objects, in some situations it is required**. 

#15


1  

Instead of talking about this specific example i will talk about general cases, so generally it is important to explicitly call delete to de-allocate memory because (in case of C++) you may have some code in the destructor that you want to execute. Like maybe writing some data to a log file or sending shutting down signal to some other process etc. If you let the OS free your memory for you, your code in your destructor will not be executed.

我将不讨论这个特定的示例,而是讨论一般的情况,因此通常显式地调用delete来去分配内存是很重要的,因为(对于c++来说)可能在析构函数中有一些代码需要执行。例如,将一些数据写入日志文件或将关闭信号发送到其他进程等等。如果您让操作系统释放了您的内存,那么您的析构函数中的代码将不会被执行。

On the other hand most operating systems will deallocate the memory when your program ends. But it is good practice to deallocate it yourself and like I gave destructor example above the OS won't call your destructor, which can create undesirable behavior in certain cases!

另一方面,大多数操作系统会在程序结束时释放内存。但这是一个很好的做法,你可以自己去处理它,就像我在操作系统上给出的析构函数不会调用你的析构函数,在某些情况下它会产生不良的行为!

I personally consider it bad practice to rely on OS to free your memory (even though it will do) the reason is if later on you have to integrate your code with a larger program you will spend hours to track down and fix memory leaks!

我个人认为,依赖OS释放内存(尽管它会这么做)是不好的做法,原因是如果以后您必须将代码与更大的程序集成在一起,您将花费数小时跟踪和修复内存泄漏!

So clean your room before leaving!

离开前一定要把房间打扫干净!

#1


74  

If in fact your question really is "I have this trivial program, is it OK that I don't free a few bytes before it exits?" the answer is yes, that's fine. On any modern operating system that's going to be just fine. And the program is trivial; it's not like you're going to be putting it into a pacemaker or running the braking systems of a Toyota Camry with this thing. If the only customer is you then the only person you can possibly impact by being sloppy is you.

如果你的问题真的是“我有这个小程序,在它退出之前我不释放几个字节可以吗?”任何现代操作系统都可以。这个程序很简单;这并不是说你要把它放进起搏器或者用丰田凯美瑞的刹车系统。如果唯一的客户是你,那么你唯一可以通过草率行事影响的人就是你。

The problem then comes in when you start to generalize to non-trivial cases from the answer to this question asked about a trivial case.

当你开始从这个问题的答案中归纳到非平凡的情况时,问题就出现了。

So let's instead ask two questions about some non-trivial cases.

让我们来问两个关于非平凡情况的问题。

I have a long-running service that allocates and deallocates memory in complex ways, perhaps involving multiple allocators hitting multiple heaps. Shutting down my service in the normal mode is a complicated and time-consuming process that involves ensuring that external state -- files, databases, etc -- are consistently shut down. Should I ensure that every byte of memory that I allocated is deallocated before I shut down?

我有一个长期运行的服务,它以复杂的方式分配和释放内存,可能涉及多个分配程序命中多个堆。在正常模式下关闭我的服务是一个复杂且耗时的过程,需要确保始终关闭外部状态(文件、数据库等)。我是否应该确保我分配的每一个字节的内存在我关闭之前被释放?

Yes, and I'll tell you why. One of the worst things that can happen to a long-running service is if it accidentally leaks memory. Even tiny leaks can add up to huge leaks over time. A standard technique for finding and fixing memory leaks is to instrument the allocation heaps so that at shutdown time they log all the resources that were ever allocated without being freed. Unless you like chasing down a lot of false positives and spending a lot of time in the debugger, always free your memory even if doing so is not strictly speaking necessary.

是的,我会告诉你为什么。对于长时间运行的服务来说,最糟糕的事情之一是它不小心泄漏了内存。随着时间的推移,即使是微小的泄漏也会累积成巨大的泄漏。查找和修复内存泄漏的标准技术是检测分配堆,以便在关机时记录所有已分配的资源,而不被释放。除非您喜欢追踪大量的误报,并在调试器中花费大量时间,否则始终要释放您的内存,即使这样做严格来说是没有必要的。

The user is already expecting that shutting the service down might take billions of nanoseconds so who cares if you cause a little extra pressure on the virtual allocator making sure that everything is cleaned up? This is just the price you pay for big complicated software. And it's not like you're shutting down the service all the time, so again, who cares if its a few milliseconds slower than it could be?

用户已经预料到关闭服务可能需要数十亿纳秒,所以谁会在意如果您对虚拟分配器造成一点额外的压力,以确保所有东西都已清理干净呢?这只是你为大型复杂软件付出的代价。这并不是说你一直在关闭服务,所以,谁会在意它是否比可能的慢了几毫秒呢?

I have that same long-running service. If I detect that one of my internal data structures is corrupt I wish to "fail fast". The program is in an undefined state, it is likely running with elevated privileges, and I am going to assume that if I detect corrupted state, it is because my service is actively being attacked by hostile parties. The safest thing to do is to shut down the service immediately. I would rather allow the attackers to deny service to the clients than to risk the service staying up and compromising my users' data further. In this emergency shutdown scenario should I make sure that every byte of memory I allocated is freed?

我有相同的长时间运行的服务。如果我发现我的一个内部数据结构是腐败的,我希望“快速失败”。程序处于未定义的状态,它可能运行时具有更高的特权,我将假设,如果我检测到已损坏的状态,那是因为我的服务正受到敌对方的主动攻击。最安全的做法是立即关闭服务。我宁愿让攻击者拒绝为客户提供服务,也不愿冒险让服务继续运行并进一步损害我的用户数据。在这个紧急关闭场景中,我是否应该确保分配的每个字节的内存都被释放?

Of course not. The operating system is going to take care of that for you. If your heap is corrupt, the attackers may be hoping that you free memory as part of their exploit. Every millisecond counts. And why would you bother polishing the doorknobs and mopping the kitchen before you drop a tactical nuke on the building?

当然不是。操作系统会帮你解决这个问题。如果您的堆损坏了,攻击者可能希望您将内存释放作为其攻击的一部分。几毫秒的时间。还有,你为什么要费心去擦门把手和拖厨房呢?

So the answer to the question "should I free memory before my program exits?" is "it depends on what your program does".

所以问题的答案是“我应该在程序退出之前释放内存吗?”

#2


39  

Yes it is good practice. You should NEVER assume that your OS will take care of your memory deallocation, if you get into this habit, it will screw you later on.

是的,这是很好的练习。你不应该假设你的操作系统会处理你的内存释放,如果你养成了这个习惯,它以后会把你搞砸。

To answer your question, however, upon exiting from the main, the OS frees all memory held by that process, so that includes any threads that you may have spawned or variables allocated. The OS will take care of freeing up that memory for others to use.

但是,要回答您的问题,在从主进程退出时,操作系统释放该进程持有的所有内存,以便包括您可能已经生成的任何线程或已分配的变量。操作系统将负责释放这些内存,供其他人使用。

#3


24  

Important note : delete's freeing of memory is almost just a side-effect. The important thing it does is to destruct the object. With RAII designs, this could mean anything from closing files, freeing OS handles, terminating threads, or deleting temporary files.

重要提示:delete释放内存几乎只是一个副作用。它所做的重要的事情是破坏对象。使用RAII设计,这意味着可以关闭文件、释放操作系统句柄、终止线程或删除临时文件。

Some of these actions would be handled by the OS automatically when your process exits, but not all.

当您的进程退出时,操作系统将自动处理其中的一些操作,但不是全部。

In your example, there's no reason NOT to call delete. but there's no reason to call new either, so you can sidestep the issue this way.

在您的示例中,没有理由不调用delete。但是也没有理由叫new,所以你可以用这种方式回避这个问题。

char str[10];

Or, you can sidestep the delete (and the exception safety issues involved) by using smart pointers...

或者,您可以通过使用智能指针来避免删除(以及涉及到的异常安全问题)……

So, generally you should always be making sure your object's lifetime is properly managed.

因此,通常您应该始终确保正确地管理对象的生命周期。

But it's not always easy: Workarounds for the static initialization order fiasco often mean that you have no choice but to rely on the OS cleaning up a handful of singleton-type objects for you.

但它并不总是那么简单:静态初始化顺序失败的工作区通常意味着您别无选择,只能依赖操作系统为您清理少量的singleton类型的对象。

#4


16  

Contrary answer: No, it is a waste of time. A program with a vast amount of allocated data would have to touch nearly every page in order to return all of the allocations to the free list. This wastes CPU time, creates memory pressure for uninteresting data, and possibly even causes the process to swap pages back in from disk. Simply exiting releases all of the memory back to the OS without any further action.

相反的回答:不,这是浪费时间。一个拥有大量已分配数据的程序几乎要访问每个页面才能将所有的分配返回到*列表中。这将浪费CPU时间,为无趣的数据创建内存压力,甚至可能导致进程从磁盘交换回页面。简单地退出将所有内存释放回操作系统,而不需要任何进一步的操作。

(not that I disagree with the reasons in "Yes", I just think there are arguments both ways)

(并不是说我不同意“是”的理由,我只是认为两种理由都有)

#5


6  

Your Operating System should take care of the memory and clean it up when you exit your program, but it is in general good practice to free up any memory you have reserved. I think personally it is best to get into the correct mindset of doing so, as while you are doing simple programs, you are most likely doing so to learn.

您的操作系统应该负责内存,并在退出程序时清理它,但通常来说,释放您所保留的任何内存都是很好的实践。我个人认为最好进入正确的心态去做,因为当你在做简单的程序时,你最有可能这样做是为了学习。

Either way, the only way to guaranteed that the memory is freed up is by doing so yourself.

无论哪种方式,确保释放内存的唯一方法就是自己这么做。

#6


4  

new and delete are reserved keyword brothers. They should cooperate with each other through a code block or through the parent object's lifecyle. Whenever the younger brother commits a fault (new), the older brother will want to to clean (delete) it up. Then the mother (your program) will be happy and proud of them.

new和delete是保留的关键字兄弟。它们应该通过代码块或父对象的生命周期相互协作。每当弟弟犯了一个错误(新的),哥哥就会想要清理(删除)它。然后母亲(你的程序)会为他们感到高兴和自豪。

#7


3  

I cannot agree more to Eric Lippert's excellent advice:

我完全同意给Eric Lippert的精彩建议:

So the answer to the question "should I free memory before my program exits?" is "it depends on what your program does".

所以问题的答案是“我应该在程序退出之前释放内存吗?”

Other answers here have provided arguments for and against both, but the real crux of the matter is what your program does. Consider a more non-trivial example wherein the type instance being dynamically allocated is an custom class and the class destructor performs some actions which produces side effect. In such a situation the argument of memory leaks or not is trivial the more important problem is that failing to call delete on such a class instance will result in Undefined behavior.

这里的其他答案为这两者提供了支持和反对的理由,但问题的真正关键是你的程序做了什么。考虑一个更重要的例子,其中被动态分配的类型实例是一个自定义类,而类析构函数执行一些产生副作用的操作。在这种情况下,内存泄漏的参数是无关紧要的,更重要的问题是,如果不调用此类类实例上的delete,将导致未定义的行为。

[basic.life] 3.8 Object lifetime
Para 4:

(基本。3.8对象生存期第4段:

A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

程序可以通过重用对象占用的存储或显式地为具有非平凡析构函数的类类型的对象调用析构函数来结束任何对象的生命周期。对于具有非平凡析构函数的类类型的对象,在对象占用的存储被重用或释放之前,程序不需要显式地调用析构函数;但是,如果没有显式调用析构函数,或者不使用delete-expression(5.3.5)来释放存储,则不应隐式地调用析构函数,任何依赖析构函数产生的副作用的程序都有未定义的行为。

So the answer to your question is as Eric says "depends on what your program does"

所以你的问题的答案正如Eric所说"取决于你的程序做什么"

#8


2  

It's a fair question, and there are a few things to consider when answering:

这是一个很公平的问题,在回答的时候要考虑以下几点:

  • some objects have more complex destructors which don't just release memory when they're deleted. They may have other side effects, which you don't want to skip.
  • 有些对象具有更复杂的析构函数,它们不仅在被删除时释放内存。他们可能有其他副作用,你不想跳过。
  • It is not guaranteed by the C++ standard that your memory will be released when the process terminates. (Of course on a modern OS it will be freed, but if you were on some weird OS which didn't do that, you'd have to free your memory properly
  • c++标准没有保证在进程终止时释放内存。(当然,在现代操作系统上,它会被释放,但是如果你在一些奇怪的操作系统上没有这样做,你必须正确地释放你的内存
  • on the other hand, running destructors at program exit can actually take up quite a lot of time, and if all the do is release memory (which would be released anyway), then yes, it makes a lot of sense to just short-circuit that and exit immediately instead.
  • 另一方面,在程序退出时运行析构函数实际上会占用很多时间,如果所有的操作都是释放内存(无论如何都会释放内存),那么是的,将其短路并立即退出是很有意义的。

#9


2  

Most operating systems will reclaim memory upon process exit. Exceptions may include certain RTOS's, old mobile devices etc.

大多数操作系统将在进程退出时回收内存。例外可能包括某些RTOS,旧的移动设备等。

In an absolute sense your app won't leak memory; however it's good practice to clean up memory you allocate even if you know it won't cause a real leak. This issue is leaks are much, much harder to fix than not having them to begin with. Let's say you decide that you want to move the functionality in your main() to another function. You'll may end up with a real leak.

在绝对意义上,你的应用程序不会泄漏内存;然而,即使你知道你分配的内存不会造成真正的泄漏,也要清理内存。这个问题是,要修复漏洞比一开始就不修复要难得多。假设您决定要将main()中的功能移动到另一个函数。你可能最终会有一个真正的漏洞。

It's also bad aesthetics, many developers will look at the unfreed 'str' and feel slight nausea :(

这也是不好的美学,许多开发人员将看到未释放的“str”,并感到轻微的恶心:

#10


2  

Why would I need to delete str if I am going to end the program anyways?

如果我要结束这个程序,为什么还要删除str ?

Because you don't want to be lazy ...

因为你不想偷懒……

I wouldn't care if that memory goes to a land full of unicorns if I am just going to exit, right?

如果我要离开的话,我不会在意那些记忆会不会进入一片满是独角兽的土地,对吧?

Nope, I don't care about the land of unicorns either. The Land of Arwen is a different matter, Then we could cut their horns off and put them to good use(I've heard its a good aphrodisiac).

不,我也不在乎独角兽的土地。亚玟的土地是不同的事情,然后我们可以砍下他们的角,好好利用他们(我听说这是一个好的春药)。

Is it just good practice?

这只是一个好的练习吗?

It is justly a good practice.

这是一种很好的做法。

Does it have deeper consequences?

它有更深层次的后果吗?

Someone else has to clean up after you. Maybe you like that, I moved out from under my parents' roof many years ago.

别人得替你收拾残局。也许你喜欢,我几年前从父母家搬出来的。

Place a while(1) loop construct around your code without delete. The code-complexity does not matter. Memory leaks are related to process time.

在代码周围放置一个while(1)循环结构,不删除。代码复杂性并不重要。内存泄漏与进程时间有关。

From the perspective of debug, not releasing system resources(file handles, etc) can cause more significant and hard to find bugs. Memory-leaks while important are typically much easier to diagnose(why can't I write to this file?). Bad style will become more of a problem if you start working with threads.

从调试的角度来看,不释放系统资源(文件句柄等)会导致更大的影响,并且很难发现bug。重要的内存泄漏通常更容易诊断(为什么我不能写入这个文件?)如果您开始使用线程,那么不良的样式将成为更大的问题。

int main()
{

    while(1)
    { 
        char* str = new char[10];

        for(int i=0;i<5;i++)
        {
            //Do stuff with str
        }
    }

    delete[] str;
    return 0;
}

#11


2  

Another reason that I haven't see mentioned yet is to keep the output of static and dynamic analyzer tools (e.g. valgrind or Coverity) cleaner and quieter. Clean output with zero memory leaks or zero reported issues means that when a new one pops up it is easier to detect and fix.

我还没有提到的另一个原因是,保持静态和动态分析工具(例如:valgrind或Coverity)的输出更干净、更安静。使用零内存泄漏或零报告问题清理输出意味着,当出现新的问题时,更容易检测和修复。

You never know how your simple example will be used or evolved. Its better to start as clean and crisp as possible.

你永远不知道你的简单例子将如何被使用或演变。越干净越好,越脆越好。

#12


2  

Not to mention that if you are going to apply for a job as a C++ programmer there is a very good chance that you won't get past the interview because of the missing delete. First - programmers don't like any leaks usually (and the guy at the interview will be surely one of them) and second - most companies (all I worked in at least) have the "no-leak" policy. Generally, the software you write is supposed to run for quite a while, creating and destroying objects on the go. In such an environment leaks can lead to disasters...

更不用说,如果你要申请一个c++程序员的工作,你很有可能会因为删除而错过面试。首先,程序员通常不喜欢任何泄漏(面试的那个人肯定是他们中的一员),其次,大多数公司(至少是我工作过的公司)都有“无泄漏”政策。通常,您编写的软件应该运行一段时间,在运行过程中创建和销毁对象。在这种环境下,泄漏会导致灾难……

#13


2  

You got a lot of professional experience answers. Here I'm telling a naive but an answer I considered as the fact.

你有很多专业经验的答案。我说的是一个幼稚但我认为是事实的答案。

  • Summary

    总结

    3. Does it have deeper consequences?

    3所示。它有更深层次的后果吗?

    A: Will answer in some detail.

    答:我会详细回答。

    2. Is it just good practice?

    2。这只是一个好的练习吗?

    A: It is considered a good practice. Release resources/memory you've retrieved when you're sure about it no longer used.

    A:这被认为是一个很好的做法。释放您已经检索到的资源/内存,当您确定它不再被使用时。

    1. Why would I need to delete str if I am going to end the program anyways?
      I wouldn't care if that memory goes to a land full of unicorns if I am just going to exit, right?
    2. 如果我要终止程序,为什么还要删除str ?如果我要离开的话,我不会在意那些记忆会不会进入一片满是独角兽的土地,对吧?

    A: You need or need not, in fact, you tell why. There're some explanation follows.

    A:你需要或者不需要,事实上,你知道为什么。有一些解释。

    I think it depends. Here are some assumed questions; the term program may mean either an application or a function.

    我认为这取决于。这里有一些假设的问题;“程序”一词可能指应用程序或函数。

    Q: Does it depend on what the program does?

    问:这取决于程序做什么吗?

    A: If universe destroyed was acceptable, then no. However, the program might not work correctly as expected, and even be a program that doesn't complete what it supposed to. You might want to seriously think about why you build a program like this?

    A:如果宇宙毁灭是可以接受的,那就没有。然而,程序可能不能正常工作,甚至是一个不能完成它应该完成的任务的程序。您可能想认真地思考为什么要构建这样的程序?

    Q: Does it depend on how the program is complicated?

    问:这取决于程序的复杂性吗?

    A: No. See Explanation.

    答:不是。看到的解释。

    Q: Does it depend on what the stability of the program is expected?

    问:这取决于程序的稳定性吗?

    A: Closely.

    密切。

    And I consider it depends on

    我认为这取决于

    1. What's the universe of the program?
    2. 程序的宇宙是什么?
    3. How's the expectation of the program that it done its work?
    4. 对这个项目的期望是什么?
    5. How much does the program care about others, and the universe where it is?

      这个程序对别人有多关心,对宇宙有多关心?

      About the term universe, see Explanation.

      关于“宇宙”一词,请参阅解释。

    For summary, it depends on what do you care about.

    总之,这取决于你关心什么。


  • Explanation

    解释

    Important: If we define the term program as a function, then its universe is application. There are many details omitted; as an idea for understanding, it's long enough, though.

    重要提示:如果我们将程序定义为函数,那么它的范围就是应用。省略了许多细节;作为一个理解的想法,它已经足够长了。

    We may ever seen this kind of diagram which illustrates the relationship between application software and system software.

    我们可能见过这种图表,它说明了应用软件和系统软件之间的关系。

    为什么要删除[]?

    But for being aware the scope of which one covers, I'd suggest a reversed layout. Since we are talking about software only, the hardware layer is omitted in following diagram.

    但是为了了解其中涉及的范围,我建议采用相反的布局。由于我们只讨论软件,因此在下面的图中省略了硬件层。

    为什么要删除[]?

    With this diagram, we realize that the OS covers the biggest scope, which is current the universe, sometimes we say the environment. You may imagine that the whole achitecture consists of a lot of disks like the diagram, to be either a cylinder or torus(a ball is fine but difficult to imagine). Here I should mention that the outmost of OS is in fact a unibody, the runtime may be either single or multiple by different implemention.

    通过这张图,我们认识到操作系统覆盖了最大的范围,即当前的宇宙,有时我们说环境。你可以想象整个猜想是由很多圆盘组成的,比如图,要么是圆柱体,要么是环面(球很好,但很难想象)。这里我要指出的是,大多数操作系统实际上是一个单主体,运行时可以是单个的,也可以是多个,由不同的实现实现。

    It's important that the runtime is responsible to both OS and applications, but the latter is more critical. Runtime is the universe of applications, if it's destroyed all applications run under it are gone.

    运行时同时负责操作系统和应用程序是很重要的,但后者更为重要。运行时是应用程序的宇宙,如果它被破坏了,那么它下面运行的所有应用程序都消失了。

    Unlike human on the Earth, we live here, but we don't consist of Earth; we will still live in other suitable environment if the time when the Earth are destroying and we weren't there.

    与地球上的人类不同,我们生活在这里,但我们不是由地球组成的;如果地球正在毁灭,而我们不在那里,我们仍将生活在其他适宜的环境中。

    However, we can no longer exist when the universe is destroyed, because we are not only live in the universe, but also consist of the universe.

    然而,当宇宙被毁灭时,我们就不复存在了,因为我们不仅生活在宇宙中,而且还包括宇宙。

    As mentioned above, the runtime is also responsible to the OS. The left circle in the following diagram is what it may looks like.

    如上所述,运行时还负责操作系统。下图中的左圆是它的样子。

    为什么要删除[]?

    This is mostly like a C program in the OS. When the relationship between an application and OS match this, is just the same situation as runtime in the OS above. In this diagram, the OS is the universe of applications. The reason of the applications here should be responsible to the OS, is that OS might not virtualize the code of them, or allowed to be crashed. If OS are always prevent they to do so, then it's self-responsible, no matter what applications do. But think about the drivers, it's one of the scenarios that OS must allowed to be crashed, since this kind of applications are treated as part of OS.

    这在操作系统中很像一个C程序。当应用程序和操作系统之间的关系匹配时,与上面操作系统中的运行时相同。在这个图中,操作系统是应用程序的宇宙。这里的应用程序应该对OS负责,因为OS可能不会虚拟化它们的代码,或者允许崩溃。如果操作系统总是阻止他们这样做,那么不管应用程序做什么,它都是自负责的。但考虑到驱动程序,这是OS必须允许崩溃的场景之一,因为这类应用程序被视为OS的一部分。

    Finally, let's see the right circle in the diagram above. In this case, the application itself be the universe. Sometimes, we call this kind of application operating system. If an OS never allowed custom code to be loaded and run, then it does all the things itself. Even it allowed, after itself is terminated, the memory goes nowhere but hardware. All the deallocation that may be necessary, is before it was terminated.

    最后,让我们看看上图中正确的圆。在这种情况下,应用程序本身就是整个宇宙。有时,我们称这种应用为操作系统。如果一个操作系统不允许自定义代码被加载和运行,那么它会自己做所有的事情。即使它允许,在它本身被终止之后,内存也只能是硬件。所有可能需要的释放都是在终止之前完成的。

    So, how much does your program care about the others? How much does it care about its universe? And how's the expectation of the program that it done its work? It depends on what do you care about.

    那么,您的程序在多大程度上关心其他程序呢?它有多关心它的宇宙?程序的期望是什么呢?这取决于你关心什么。

#14


2  

TECHNICALLY, a programmer shouldn't rely on the OS to do any thing. The OS isn't required to reclaim lost memory in this fashion.

从技术上讲,程序员不应该依赖操作系统做任何事情。操作系统不需要以这种方式恢复丢失的内存。

If you do write the code that deletes all your dynamically allocated memory, then you are future proofing the code and letting others use it in a larger project.

如果您确实编写了删除所有动态分配内存的代码,那么您就是在将来验证代码,并让其他人在更大的项目中使用它。

Source: Allocation and GC Myths(PostScript alert!)

来源:分配和GC神话(PostScript alert!)

Allocation Myth 4: Non-garbage-collected programs should always
deallocate all memory they allocate.

The Truth: Omitted deallocations in frequently executed code cause
growing leaks. They are rarely acceptable. but Programs that retain
most allocated memory until program exit often perform better without
any intervening deallocation. Malloc is much easier to implement if
there is no free.

In most cases, deallocating memory just before program exit is
pointless. The OS will reclaim it anyway. Free will touch and page in
the dead objects; the OS won't.

Consequence: Be careful with "leak detectors" that count allocations.
Some "leaks" are good!
  • I think it's a very poor practice to use malloc/new without calling free/delete.

    我认为使用malloc/new而不调用free/delete是非常糟糕的做法。

  • If the memory's going to get reclaimed anyway, what harm can there be from explicitly deallocating when you need to?

    如果内存无论如何都会被回收,那么在需要时显式地释放内存又有什么害处呢?

  • Maybe if the OS "reclaims" memory faster than free does then you'll see increased performance; this technique won't help you with any program that must remain running for any long period of time.

    也许如果操作系统“回收”内存的速度比免费快,那么您将看到性能的提高;这种技术对任何必须长时间运行的程序都没有帮助。

Having said that, so I'd recommend you use free/delete.

说到这里,我建议您使用free/delete。


If you get into this habit, who's to say that you won't one day accidentally apply this approach somewhere it matters?

如果你养成了这个习惯,谁又能说你不会有一天不小心把这个习惯应用到重要的地方呢?


One should always deallocate resources after one is done with them, be it file handles/memory/mutexs. By having that habit, one will not make that sort of mistake when building servers. Some servers are expected to run 24x7. In those cases, any leak of any sort means that your server will eventually run out of that resource and hang/crash in some way. A short utility program, ya a leak isn't that bad. Any server, any leak is death. Do yourself a favor. Clean up after yourself. It's a good habit.

在处理完资源之后,应该总是重新分配资源,无论是文件句柄/内存/互斥对象。有了这个习惯,在构建服务器时就不会犯这样的错误了。一些服务器预计运行24x7。在这些情况下,任何类型的泄漏都意味着您的服务器最终将耗尽该资源并以某种方式挂起/崩溃。一个简短的实用程序,对,泄漏不是那么糟糕。任何服务器,任何泄漏都是死亡。帮自己一个忙。收拾自己。这是一个好习惯。


Think about your class 'A' having to deconstruct. If you don't call
'delete' on 'a', that destructor won't get called. Usually, that won't
really matter if the process ends anyway. But what if the destructor
has to release e.g. objects in a database? Flush a cache to a logfile?
Write a memory cache back to disk? **You see, it's not just 'good
practice' to delete objects, in some situations it is required**. 

#15


1  

Instead of talking about this specific example i will talk about general cases, so generally it is important to explicitly call delete to de-allocate memory because (in case of C++) you may have some code in the destructor that you want to execute. Like maybe writing some data to a log file or sending shutting down signal to some other process etc. If you let the OS free your memory for you, your code in your destructor will not be executed.

我将不讨论这个特定的示例,而是讨论一般的情况,因此通常显式地调用delete来去分配内存是很重要的,因为(对于c++来说)可能在析构函数中有一些代码需要执行。例如,将一些数据写入日志文件或将关闭信号发送到其他进程等等。如果您让操作系统释放了您的内存,那么您的析构函数中的代码将不会被执行。

On the other hand most operating systems will deallocate the memory when your program ends. But it is good practice to deallocate it yourself and like I gave destructor example above the OS won't call your destructor, which can create undesirable behavior in certain cases!

另一方面,大多数操作系统会在程序结束时释放内存。但这是一个很好的做法,你可以自己去处理它,就像我在操作系统上给出的析构函数不会调用你的析构函数,在某些情况下它会产生不良的行为!

I personally consider it bad practice to rely on OS to free your memory (even though it will do) the reason is if later on you have to integrate your code with a larger program you will spend hours to track down and fix memory leaks!

我个人认为,依赖OS释放内存(尽管它会这么做)是不好的做法,原因是如果以后您必须将代码与更大的程序集成在一起,您将花费数小时跟踪和修复内存泄漏!

So clean your room before leaving!

离开前一定要把房间打扫干净!