【问题标题】:What happens if I forget to deallocate memory in C++如果我忘记在 C++ 中释放内存会怎样
【发布时间】:2015-07-06 11:06:53
【问题描述】:

我有一个关于 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]-->[0x86229c]-->[0x86228c]-->[0x86227c]-->[0x8615bc]-->[NULL]

【问题讨论】:

  • 如果您从使用标准容器开始 - 例如std::stringstd::vectorstd::set - 如果您“按值”存储元素,它们会自动为您管理和释放内存。当您必须使用指针跟踪或以其他方式处理元素时,更喜欢“智能指针”,它可以强制执行所有权/生命周期模型并避免泄漏:特别是 C++11 标准库提供了 std::unique_ptrstd::shared_ptr,它们非常有用.

标签: c++ memory-management


【解决方案1】:

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

然而,在你用完资源后不释放资源会导致泄漏,在内存的情况下你将会有内存泄漏。对于长时间运行的进程,这些泄漏可能会累积,直到所有资源都用完。


即使在进程终止时自动释放内存和其他资源,在退出进程之前显式释放分配的资源通常仍被认为是一种不错的方式。

【讨论】:

  • 谢谢!这就是我要找的解释!
【解决方案2】:

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

也就是说,最好不要指望这种行为。例如,您可以在构造函数/析构函数中包含已分配对象的计数。如果它们在程序退出之前都归零,那么您可以很好地检查内存泄漏。如果这些计数不为零,则说明某处存在内存泄漏。

【讨论】:

    【解决方案3】:

    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 指向的整数,尽管该整数不再可访问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 2015-12-11
      • 1970-01-01
      • 2013-08-31
      • 2010-10-26
      • 2014-10-04
      相关资源
      最近更新 更多