2015-07-06 32 views
1

我有一个关于C++内存管理的问题。据我所知,没有必要在Java中取消分配内存,因为未使用的对象有时会被JVM垃圾回收器清除。我的观点是,如果我忘记使用C++释放内存,那么在我重新启动机器并且内存中的数据丢失之前,已使用的内存地址将被占用?例如,在下面的代码我有一个简单的链表,你可以看到,我不释放内存(在析构函数评论):如果我忘记释放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] - > [0x86229c] - > [0x86228c] - > [0x86227c] - > [0x8615bc] - > [NULL]

+0

[当你在malloc之后没有自由时真的会发生什么?](http://stackoverflow.com/questions/654754/what-really-happens-when-you-dont-free-after-malloc ) –

+0

如果您使用标准容器开始 - 例如'std :: string','std :: vector','std :: set' - 如果你通过“value”存储元素,他们会自动管理和释放内存。当你必须使用指针来跟踪或以其他方式处理元素时,首选“智能指针”,它可以执行所有权/生命周期模型并避免泄漏:特别是,C++ 11标准库提供'std :: unique_ptr'和'std :: shared_ptr'这非常有用。 –

回答

4

这取决于操作系统。大多数现代操作系统都会跟踪每个进程分配的内存,因此当进程退出时,进程分配的所有内存都应该释放。

但是,你与他们完成后会导致泄漏,在记忆的情况下,你将有内存没有释放资源泄漏。对于长时间运行的流程,这些泄漏可能会累积,直到所有资源用完。


的内存等资源被自动释放进程终止即使,它往往还是考虑好作风退出过程之前显式释放分配的资源。

+0

谢谢!这是我正在寻找的解释! –

1

C++没有Java那样的垃圾收集器,程序员有义务释放动态分配的内存。操作系统会在应用程序终止时清除为应用程序分配的内存,但有些情况下必须由编程人员执行释放,否则会导致内存泄漏。

#include <iostream> 
using namespace std; 
class test { 
    public: 
    int cl; 
}; 

int main() 
{ 
    test *p; 
    p=new(test); 
    p->cl=5; 
    return 0; 
} 

当上述程序结束,将释放指针p,但尽管该整数不再访问不会被释放p指向的整数。

1

除非您正在使用某种精简的实时操作系统,否则在进程退出时系统无法恢复所有内存的可能性极小。

也就是说,不要指望这种行为是一个好习惯。例如,您可以在您的构造函数/析构函数中包含已分配对象的计数。如果它们在程序退出之前全部归零,则可以很好地检查内存泄漏。如果这些计数是非零的,你就会在某处发生内存泄漏。

相关问题