显然,维基百科有关于该主题的大量信息,但我想确保我理解.从我可以告诉它的重要性来理解堆栈/堆关系真正了解内存泄漏?
所以这就是我(我想)的理解.更正是非常受欢迎的!
首次启动程序时,会分配一块内存,例如0x000到0xFFF.第一部分(比如0x000到0x011)是加载程序代码的代码/文本段.
+--------------+ 0x011
| Program Code |
+--------------+ 0x000
Run Code Online (Sandbox Code Playgroud)
然后你有堆栈(比如0x012到0x7ff)保存局部变量,它们被存储/检索FIFO.所以,如果你有类似的东西
char middleLetter(string word){
int len = word.length();
return word[len/2];
}
int main(){
int cool_number;
char letter;
letter = middleLetter("Words");
...
Run Code Online (Sandbox Code Playgroud)
然后你的变量将被分配在堆栈上,如下所示:
+-------------+ 0x7ff
| |
| |
| |
| ... |
| len |
| letter |
| cool_number |
+-------------+ 0x012
Run Code Online (Sandbox Code Playgroud)
当然,如果你在某处(使用malloc或new)分配内存,但从不释放它,那么你的堆可能看起来像这样,你现在有内存泄漏:
+-------------+ 0xfff
| |
| malloc(20) | 0xf64
| malloc(50) | 0xf32
| malloc(50) | 0xf00
| ... |
| |
+-------------+ 0x800
Run Code Online (Sandbox Code Playgroud)
这意味着虽然您可以使用指针算法直接访问0xf32,但OS /您的程序认为已经占用了内存位置0xf00-0xf46,并且在您的程序关闭之前不会再使用这些位置进行存储.内存被释放.但共享内存怎么样?维基百科说它不会被发布(直到你的计算机重新启动?).你怎么知道它是否是共享内存?
这是一个非常好的基本理解吗?有什么我错过/有错吗?谢谢你的期待!
小智 9
好像你理解它 - 有一个例外:在你的例子中,len是一个堆栈变量,就像其他一切一样.new或者malloc在堆上创建,其他所有内容(本地变量等)都在堆栈上.主要的局部变量与任何其他函数的变量没有区别.
共享内存是一种相当罕见的情况,你通常不需要它,因此你不会拥有它,除非你明确要求它(否则,一些随机的其他进程可能会使用你的进程使用的相同内存 - 显然,这会严重破坏事情).
您的函数变量通常也在堆栈中,而不是堆.在大多数系统中,堆用于动态分配.通常的内存泄漏情况是
内存泄漏变得简单:每当您使用 malloc/new 分配内存并且在使用完该内存后不使用 free/delete 释放它时...都会导致内存泄漏!分配的内存将保留在那里,并且该空间将不会再被您的程序使用。
当泄漏发生在多次调用的函数上时,这是一个严重的问题,导致每次调用该函数时泄漏都会变得越来越大。