以下代码有明显的内存泄漏:
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;
}
在程序的持续时间内,内存是否可以恢复? 程序可以写入丢失的内存,并达到没有内存丢失的状态吗? 当程序仍在运行时,操作系统能否恢复它?
答案 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等上阅读有关智能指针的更多信息。
答案 2 :(得分:1)
是的,在程序期间内存丢失。操作系统无法知道您丢失了对此内存位置的所有引用。
这是C / C ++和Java / C#之间的根本区别之一。
垃圾收集是一种机制,用于确定内存位置是否不再有任何引用它的内容,并且允许操作系统回收未使用的内存 - 并且在C / C ++中不可用
答案 3 :(得分:1)
在程序的持续时间内,每个内存都会被恢复吗?
否:除非您神奇地猜测丢失变量的地址并调用delete
,否则它就会消失。
程序现在可以写入这个内存,并达到没有内存丢失的状态吗?
否 - 再次,一旦丢失了对分配的内存区域地址的引用,就无法恢复相应的内存块。
当程序仍在运行时,操作系统能否恢复它?
不,操作系统在进程退出之前不会恢复该内存。