Back
Featured image of post 程序执行时的栈和堆

程序执行时的栈和堆

在 C语言中,程序运行时会存在 两种不同的内存分配方式。

接下来,我们从 内存分配方式内存地址增长碎片 三个方面来对比

内存分配方式

:系统自动分配和释放,主要存放程序中的实际参数和局部变量。

:程序员自己分配和释放,可以动态拓展和搜索的内存空间,程序调用 malloc、new、free 之类的函数堆大小会变化。

内存地址增长

:向着内存地址减小的方向增长,由内存的高地址向低地址方向增长。

:向着内存地址增长方向增长,从内存地址的低地址向高地址方向增长。

碎片

:因为是连续分配的空间,所以没有碎片问题。

:频繁的 malloc 或 free 会造成内存空间的不连续。

示例

下面是一个 C++ 代码的例子:

# include <iostream>

using namespace std;

void stack_example(){
    int stack_var = 10;		// 局部变量,在栈中分配内存
    cout << "Stack variable: " << stack_var << endl;
}

void heap_example(){
    int * heap_var = new int(20);		// new,在堆中分配内存
    cout << "Heap variable:" << *heap_var << endl;
    delete heap_var;		// 释放堆内存
}

int main(){
    stack_example();
    heap_example();
    return 0;
}

注意,当你在堆上分配内存时,需要使用完成后进行释放,否则可能会导致内存泄露的问题。

内存泄露就是指,你向程序申请内存后没有归还给系统,那么这个对象就会一直占用这块内存。

拓展:静态变量

全局静态变量和局部静态变量都是存储在静态存储区之中的。

区别就是,局部静态变量会在函数销毁时依旧驻留在内存中,直到程序结束。

但是,如果是动态分配的静态变量,它需要在多个内存之间共享并保存值,就会存放在堆区,这样它的生命周期会伴随程序的整个过程。

比如,我们可以看一个 C++ 的例子:

# include <iostream>

using namespace std;

void allocate_static(){
    static int* heap_var = new int(20);
    cout << "Heap variable:" << *heap_var << endl;
}

int main(){
    allocate_static();
    return 0;
}
Built with Hugo
Theme Stack designed by Jimmy
© Licensed Under CC BY-NC-SA 4.0