在学习静态成员的时候,不少知识点设计到了内存这一块,之前在学习C语言和数据结构的时候也在这一块遇到了不少迷惑,今天就打开这扇门,一探究竟,持续补充~
对一个程序来说,它会占用哪些内存:
静态区/全局数据区:
用来存放全局变量、静态全局变量、静态局部变量。在程序结束后由系统回收。
这个区域可以可能分成以下内存区域(查了一些资料,用了汇编原理来介绍此块,目前仅作了解):
- 1.BSS段(bss segment):BSS(Block Started by Symbol),用来存放程序中未初始化的全局变量和静态变量的一块内存区域,在程序运行之前会被自动清0。
- 2.数据段(data segment):用来存放程序中已初始化的全局变量的一块内存区域。
文字常量区
用来存放常量字符串,程序结束后由系统自动释放。
程序代码区
用来存放函数体的二进制代码。
栈(stack)
存放函数的参数名,局部变量的名,由编译器自动分配释放。
堆(heap)
存放动态分配的内存,如用malloc和new动态分配的内存,由程序员自己释放,如free和delete,如果程序员不释放(warning!可能会造成内存泄露),程序结束后系统可能会对其回收。
下面以几行代码来认识上述的几个区域:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
static int a = 1; //存放在全局数据区(初始化区)
int b; //存放在全局数据区(未初始化区,会被自动清0)
int main()
{
int c = 0; //存放在栈区
char d[100] = "helloworld"; //"helloworld"存放在常量区,s存放在栈区
int* e = (int*)malloc(10*sizeof(int)); //申请的空间存放在堆区
int* f = new int [10]; //申请的空间存放在堆区
static int g = 0; //存放在全局数据区(初始化区)
return 0;
}
从网络上找了两张图,我觉得非常形象:


接下来对这些区域的相关知识再作补充:
栈(stack)和堆(heap)
- 1.栈是一种后入先出的数据结构,在Windows中,栈是由高地址向低地址生长的,这表明栈顶地址以及栈的最大容量是系统规定好的,一般情况下是2M,如果申请的空间超过了栈中剩余的空间,就会发生栈溢出的问题(Overflow)。而堆(这里的堆不是数据结构中的堆)是向高地址扩展的数据结构,是不连续的内存区域,因为系统使用的是链表来存放那些空闲的内存地址的,而链表的遍历是由低地址向高地址。堆的大小和计算机的内存有关,所以比栈大得多,一般有4G,所以当我们定义一个大数组时,放在栈中可能会导致栈溢出,放在堆中就没问题。
- 2.关于效率,栈虽然空间小,但是由系统自动分配,速度较快,而堆是程序员动态申请的内存,速度比较慢,而且如果程序员不手动释放自己申请的内存,可能会发生一些内存泄漏,但是十分方便,所以当我们定义一个变量时,需要考虑一下后果和效率再选择合适的地方去定义这些变量。
-3. ....
先写到这,本想举一个栈向下生长和堆向上生长的例子,但是我发现再网页上和VS上的结果不一样,网上暂时没查询到有效的信息,暂时记录一下,另外,关于"段"的知识还没有学习过,但是涉及到内存,肯定时绕不过的,慢慢补充吧,学无止境嘛!
2020年2月16日
网友评论