C++内存分配管理

Preface

最近在撸一道Dijkstra算法题目的时候犯了一个这样的错误。

我创建一个比较大的数组写在main函数中,整个程序就会退出,而如果放在全局就可以正常运行。

了解过后,原来涉及到C++内存管理的问题。本文做下记录。


问题重现

1
2
3
4
5
6
7
8
9
#include<iostream>
using namespace std;

int main(){
int a[2505][2505];
int x;
cin >>x;
return 0;
}

上面这段代码,运行的时候会发生错误

进程已结束,退出代码139 (interrupted by signal 11: SIGSEGV)

而将a数组放在全局就正常运行

1
2
3
4
5
6
7
8
9
#include<iostream>
using namespace std;

int a[2505][2505];
int main(){
int x;
cin >>x;
return 0;
}

解释

在C++中内存管理十分重要,有五中内存分配方式, 分别是堆、栈、自由存储区、全局/静态存储区和常量存储区

:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

:就是那些由 new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个 delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

自由存储区 :就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

全局/静态存储区 :全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

常量存储区 :这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。


在最初,那个错误的写法当中,将a数组在main函数当中创建,占用的内存来自栈空间,而栈空间的大小比较小,所以就会出现最初的错误。当数组在全局中创建时,数组在全局/静态存储区分配内存,而此处的空间会大不少,也就能正常运行了。

其他内存管理方面的知识,可以看文末的参考链接,就不做摘抄了。


参考

C/C++内存管理详解
内存分配详解、指针与数组

关注我的微信公众号[李一二],即时看更多的文章