在C / C ++程序期间,泄漏的内存是否会一直丢失?

时间:2012-11-27 03:31:47

标签: c++ c memory memory-management operating-system

以下代码有明显的内存泄漏:

void Memory_Leak(void);
void Lots_Of_Other_Stuff(void);

int main(){

    Memory_Leak();
    Lots_Of_Other_Stuff();
}

void Memory_Leak(void)
{
  int *data = new int;
  *data = 15;
  return;
}
void Lots_Of_Other_Stuff(void){
    //allocates/deletes more memory
    //calls functions
    //etc..
    return;
}

在程序的持续时间内,内存是否可以恢复? 程序可以写入丢失的内存,并达到没有内存丢失的状态吗? 当程序仍在运行时,操作系统能否恢复它?

4 个答案:

答案 0 :(得分:2)

不,在程序完成执行之前,内存将无法恢复。

没有。如果你能够写入那个内存,那么首先就没有内存泄漏,因为你仍然必须有一些指向已分配内存的指针(用new或malloc分配新内存永远不会给你相同的已分配内存)。

没有。操作系统无法知道您的程序仍然没有使用该内存,因此无法恢复它。

答案 1 :(得分:2)

标准C ++没有办法知道你不再使用内存了。

存在一些特定于平台的机制,用于内省堆,通常用于调试,例如

http://msdn.microsoft.com/en-us/library/974tc9t1(v=vs.80).aspx

理论上,在运行Memory_Leak()之前,可能会使用类似的东西来获取堆状态的“快照”。完成后,你可以寻找任何你认为是泄漏的东西并释放它。 但不要这样做。只提及它的彻底性。

避免泄漏的C ++方法是使用“智能”指针而不是“raw / naked / dumb / C-style”指针。例如:

void Memory_Leak(void) // actually, with this change it won't leak anymore...
{
    shared_ptr<int> data (new int);
    *data = 15;
    return;
}

共享指针是一个带有析构函数的对象,因此它有机会在生命周期结束时运行一些代码。该代码释放内存。在这种情况下,局部变量data在return语句中结束其生命,如果该shared_ptr尚未复制并存储在别处,那么整数存储器上保留的引用计数将为零。这样就可以释放内存。

您可以在StackOverflow,Wikipedia,Google等上阅读有关智能指针的更多信息。

http://en.wikipedia.org/wiki/Smart_pointer

答案 2 :(得分:1)

是的,在程序期间内存丢失。操作系统无法知道您丢失了对此内存位置的所有引用。

这是C / C ++和Java / C#之间的根本区别之一。

垃圾收集是一种机制,用于确定内存位置是否不再有任何引用它的内容,并且允许操作系统回收未使用的内存 - 并且在C / C ++中不可用

答案 3 :(得分:1)

  

在程序的持续时间内,每个内存都会被恢复吗?

否:除非您神奇地猜测丢失变量的地址并调用delete,否则它就会消失。

  

程序现在可以写入这个内存,并达到没有内存丢失的状态吗?

否 - 再次,一旦丢失了对分配的内存区域地址的引用,就无法恢复相应的内存块。

  

当程序仍在运行时,操作系统能否恢复它?

不,操作系统在进程退出之前不会恢复该内存。