简体   繁体   English

释放动态分配的内存

[英]Freeing dynamically allocated memory

In C++, when you make a new variable on the heap like this: 在C ++中,当您在堆上创建一个新变量时,如下所示:

int* a = new int;

you can tell C++ to reclaim the memory by using delete like this: 你可以告诉C ++使用delete这样回收内存:

delete a;

However, when your program closes, does it automatically free the memory that was allocated with new? 但是,当程序关闭时,是否会自动释放分配了新内存的内存?

Yes, it is automatically reclaimed, but if you intend to write a huge program that makes use of the heap extensively and not call delete anywhere, you are bound to run out of heap memory quickly, which will crash your program. 是的,它会被自动回收,但是如果你打算编写一个大量使用堆的大型程序而不是在任何地方调用delete ,你必然会快速耗尽堆内存,这会使程序崩溃。

Therefore, it is a must to carefully manage your memory and free dynamically allocated data with a matching delete for every new (or delete [] if using new [] ), as soon as you no longer require the said variable. 因此,只要您不再需要所述变量,就必须仔细管理您的内存并释放动态分配的数据,并为每个new的匹配delete (如果使用new [] ,则delete [] new [] )。

When the process is terminated the memory is reclaimed back by the OS. 当进程终止时,操作系统将回收内存。 Of course this argument shouldn't in any case be used to not perform proper memory management by the program. 当然,在任何情况下都不应该使用该参数来不对程序执行适当的内存管理。

Don't let people tell you yes. 不要让别人告诉你是的。 C++ has no concept of an OS, so to say "yes the OS will clean it up" is no longer talking about C++ but about C++ running on some environment, which may not be yours. C ++没有操作系统的概念,所以说“是的操作系统将清理它”不再是在谈论C ++,而是关于在某些环境中运行的C ++,这可能不是你的。

That is, if you dynamically allocate something but never free it you've leaked. 也就是说,如果你动态分配一些东西但从未释放它,你就会泄露。 It can only end its lifetime once you call delete / delete[] on it. 一旦你调用了delete / delete[] ,它就只能结束它的生命周期。 On some OS's (and almost all desktop OS's), memory will be reclaimed (so other programs may use it.) But memory is not the same as resource! 某些操作系统(和几乎所有的桌面操作系统的),内存会被回收(所以其他程序可以使用它。)但是内存是一样的资源! The OS can free all the memory it wants, if you have some socket connection to close, some file to finish writing to, etc, the OS might not do it. 操作系统可以释放它想要的所有内存,如果你有一些套接字连接关闭,一些文件完成写入等,操作系统可能不会这样做。 It's important not to let resources leak. 重要的是不要让资源泄漏。 I've heard of some embedded platforms that won't even reclaim the memory you've not freed, resulting in a leak until the platform is reset. 我听说过一些嵌入式平台甚至无法回收你没有释放的内存,导致漏洞直到平台重置。

Instead of dynamically allocating things raw (meaning you're the one that has to explicitly delete it), wrap them into automatically allocated (stack allocated) containers; 而不是动态分配原始的东西(意味着你是必须明确删除它的东西),将它们包装成自动分配的(堆栈分配的)容器; not doing so is considered bad practice, and makes your code extremely messy. 不这样做被认为是不好的做法,并使你的代码非常混乱。

So don't use new T[N] , use std::vector<T> v(N); 所以不要使用new T[N] ,使用std::vector<T> v(N); . The latter won't let a resource leak occur. 后者不会让资源泄漏。 Don't use new T; 不要使用new T; , use smart_ptr p(new T); ,使用smart_ptr p(new T); . The smart pointer will track the object and delete it when it's know longer used. 智能指针将跟踪对象并在知道更长时间时将其删除。 This is called Scope-bound Resource Management (SBRM, also known as the dumber name Resource-Acquisition is Initialization, or RAII.) 这称为范围限制资源管理(SBRM,也称为数字名称资源获取是初始化,或RAII。)

Note there is no single " smart_ptr ". 请注意,没有单一的“ smart_ptr ”。 You have to pick which one is best. 你必须选择哪一个是最好的。 The current standard includes std::auto_ptr , but it's quite unwieldy. 目前的标准包括std::auto_ptr ,但它非常笨重。 (It cannot be used in standard containers.) Your best bet is to use the smart pointers part of Boost, or TR1 if your compiler supports it. (它不能用在标准容器中。)最好的办法是使用Boost的智能指针部分,如果编译器支持它,则使用TR1。 Then you get shared_ptr , arguably the most useful smart pointer, but there are many others. 然后你得到shared_ptr ,可以说是最有用的智能指针,但还有很多其他指针。

If every pointer to dynamically allocated memory is in an object that will destruct (ie, not another object that is dynamically allocated), and that object knows to free the memory, that pointer is guaranteed to be freed. 如果每个指向动态分配内存的指针都在一个将要销毁的对象中(即,不是另一个动态分配的对象),并且该对象知道释放内存,则保证释放该指针。 This question shouldn't even be a problem, since you should never be in a position to leak. 这个问题甚至不应该是一个问题,因为你永远不应该泄漏。

No, it's your responsibility to free it. 不,你有责任解放它。 Also, a must be a pointer, so it should be: 此外, a必须是一个指针,所以它应该是:

int *a = new int;
delete a;

This excellent answer by Brian R. Bondy details why it's good practice to free the memory allocated by a . Brian R. Bondy的这个出色的答案详细解释了为什么释放a分配的内存是a好习惯。

It is important to explicitly call delete because you may have some code in the destructor that you want to execute. 显式调用delete非常重要,因为您可能在析构函数中有一些要执行的代码。 Like maybe writing some data to a log file. 就像将一些数据写入日志文件一样。 If you let the OS free your memory for you, your code in your destructor will not be executed. 如果让操作系统为您释放内存,则不会执行析构函数中的代码。

Most operating systems will deallocate the memory when your program ends. 大多数操作系统将在程序结束时释放内存。 But it is good practice to deallocate it yourself and like I said above the OS won't call your destructor. 但是好的做法是自己解除分配,就像上面说的那样操作系统不会调用你的析构函数。

As for calling delete in general, yes you always want to call delete, or else you will have a memory leak in your program, which will lead to new allocations failing. 至于通常调用delete,是的,你总是想调用delete,否则你的程序会有内存泄漏,这将导致新的分配失败。

No, when the program exits ("closes") the dynamically allocated memory is left as is 不,当程序退出(“关闭”)时,动态分配的内存保持不变

EDIT: 编辑:

Reading the other answers, I should be more precise. 阅读其他答案,我应该更精确。 The destructors of dynamically allocated objects will not run but the memory will be reclaimed anyway by any decent OS. 动态分配对象的析构函数不会运行,但任何体面的操作系统都会回收内存。

PS: The first line should read PS:第一行应该阅读

int* a = new int;

When your process terminates, the OS does regain control of all resources the process was using, including memory. 当您的进程终止时,操作系统会重新控制进程正在使用的所有资源,包括内存。 However, that, of course, will not cause C++'s destructors to be necessarily run, so it's not a panacea for not explicitly freeing said resources (though it won't be a problem for int or other types with noop dtors, of course;-). 然而,当然,这不会导致C ++的析构函数必然运行,因此它不是没有明确释放所述资源的灵丹妙药(当然,对于int或其他类型的noop dtors来说,这不会是一个问题; - )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM