我对C ++中的内存管理有疑问。据我所知,没有必要在Java中释放内存,因为JVM垃圾收集器有时会删除未使用的对象。我的观点是,如果我忘记在C ++中释放内存,使用的内存地址将被占用,直到我重新启动机器并且内存中的数据丢失?例如,在下面的代码中我有一个简单的链表,你可以观察到我没有释放内存(在析构函数中注释):
#include <iostream>
using namespace std;
typedef struct Node{
Node* next;
int id;
} *ListPtr;
class LinkedList{
public:`ListPtr header;
LinkedList(){
header = NULL;
}
~LinkedList(){
/*
ListPtr a = header,b;
while(a != NULL)
{
b = a;
a = a -> next;
delete b;
}
delete a,b;
cout << "Memory freed!"<< endl;
*/
}
public: void Insert(){
ListPtr new_element = new Node;
new_element -> next = NULL;
if(header == NULL){
header = new_element;
header -> id = 0;
}
else{
new_element -> next = header;
new_element -> id = header -> id + 1;
header = new_element;
}
}
public: void Print(){
ListPtr curr = header;
while(curr != NULL){
cout << "[" << &curr -> id << "]" << "-->";
curr = curr -> next;
}
cout << "[NULL]"<<endl;
}};
int main(){
LinkedList list;
list.Insert();
list.Insert();
list.Insert();
list.Insert();
list.Insert();
list.Print();
return 0;
}
是否意味着在关闭机器之前这些内存地址将被占用?完成程序执行后整数等变量会发生什么?我可以免费使用吗?
该计划的输出是: 的 [0x8622ac] - GT; - ; 0x86228c] - GT; 0x86227c] - GT; 0x8615bc] - GT; [0x86229c] GT [NULL]
答案 0 :(得分:4)
这取决于操作系统。大多数现代操作系统都会跟踪每个进程分配的内存,因此当进程退出时,应该释放进程分配的所有内存。
但是,在您完成资源后不释放资源会导致泄漏,如果是内存,则会出现内存泄漏。对于长时间运行的进程,这些泄漏可能会累积,直到所有资源都用完为止。
即使在进程终止时自动释放内存和其他资源,在退出进程之前,它仍然被认为是明确释放已分配资源的好方式。
答案 1 :(得分:1)
C ++没有像Java这样的垃圾收集器,程序员有责任释放动态分配的内存。当应用程序终止时,操作系统会清除为应用程序分配的内存,但是在某些特定情况下,程序员必须执行解除分配,否则会导致内存泄漏。
var Constructor = function (params) {
var config = params;
var data = params.data;
// Privileged function pattern:
// By using a closure, this method has access to private members.
this.getData = function (b) {
return data;
};
};
// Note: Changed to `new` in order to instantiate the class
var cns = new Constructor({
data: 123
});
console.log(cns.getData(0));
当上面的程序终止时,它将释放指针p,但不会释放p指向的整数,尽管该整数不再可访问。
答案 2 :(得分:1)
除非您使用某种精简的实时操作系统,否则在进程退出时系统无法恢复所有内存。
那就是说,不要依赖这种行为是一种好习惯。例如,您可以在构造函数/析构函数中包含已分配对象的计数。如果在程序退出之前它们都归零,那么您可以很好地检查内存泄漏。如果这些计数不为零,则会在某处出现内存泄漏。