1

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

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

4 回答 4

2

不,在您的程序完成执行之前不会恢复内存。

不。如果您能够覆盖该内存,那么首先就不会发生内存泄漏,因为您仍然必须有一些指向已分配内存的指针(使用 new 或 malloc 分配新内存永远不会给您相同的已分配内存)。

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

于 2012-11-27T03:33:21.070 回答
2

标准 C++ 无法知道您不再使用内存。

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

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

从理论上讲,您可以在运行Memory_Leak(). 然后在它完成后,你可以寻找任何你认为是泄漏的东西并释放它。 但不要这样做。 只是为了彻底而提及它。

避免泄漏的 C++ 方法是使用“智能”指针而不是“原始/裸/哑/C 样式”指针。例如:

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

于 2012-11-27T03:45:25.327 回答
1

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

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

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

于 2012-11-27T03:35:26.063 回答
1

在程序执行期间,内存是否会全部恢复?

不:除非你神奇地猜到了丢失变量的地址并调用delete它,否则它就消失了。

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

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

操作系统可以在程序仍在运行时恢复它吗?

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

于 2012-11-27T03:36:33.240 回答