[toc]

# 基础知识

C++ 内存分区:栈、堆、全局 / 静态存储区、常量存储区、代码区

  • 栈:存放函数的局部变量、函数参数、返回地址等,由编译器自动分配和释放
  • 堆:动态申请的内存空间,就是由 malloc 分配的内存块,由程序员控制它的分配和释放,如果程序执行结束还没有释放,操作系统会自动回收。
  • 全局区 / 静态存储区 (.bss 段和.data 段): 存放全局变量和静态变量,程序运行结束操作系统自动释放,在 C 语言中,未初始化的放在.bss 段中,初始化的放在.data 段中,C++ 中不再分区了
  • 常量存储区 (.data 段) : 存放的是变量,不允许修改,程序运行结束自动释放
  • 代码区 (.text 段): 存放代码,不允许修改,但可以执行。编译后的二进制文件存放在这里

说明:
- 从操作系统本身来讲,以上存储区在内存中的分布是如下形式 (从低地址到高地址): .text 段–>.data 段–>.bss 段–> 堆–>unused–> 栈–>env 对于 bss 的详见 关于 text 段、data 段和 bss 段

# 实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
using namespace std;

/*
说明: C++中不再区分初始化和未初始化的全局变量、静态变量的存储区,如果非要区分下述程序标注在了括号中
*/

int g_var = 0; //g_var 在全局区(.data 段)
char *gp_va; // gp_var 在全局区(.bss 段)

int main(){
int var;//var在栈区
char *p_var;//p_var在栈区
char arr[] = "abc";//arr为数组变量,存储在栈区;"abc"为字符串常量,存储在常量区
char *p_var1 = "123456";//p_var1在栈区,"123456"为字符串常量,存储在常量区
static int s_var = 0;//s_var 为静态变量,存储在静态存储区(.data段)

p_var = (char *)malloc(10);//分配得来的10个字节的区域在堆区
free(p_var);
return 0;
}

# 关于 text 段、data 段和 bss 段

# bss

Block Started by Symbol 通常是指用来存放程序中未初始化的全局变量的一块内存区域,BSS 段属于静态内存分配,用户应该将它定义在可读写的 RAM 区内, 源程序中使用malloc分配的内存就是这一块.

# text

text 段是程序代码段,它是由编译器在编译连接时自动计算的

# data

静态初始化的数据,所以有初值的全局变量和 static 变量在 data 区,他和程序大小无关,和全局变量,常量数量有关.

# stack

栈常用来存放暂时存储的信息,所以当调用函数或过程后,将会清除栈上保存的局部变量,函数调用信息及其他信息。栈是系统自动分配的,系统自动分配栈空间时,如果剩余空间大于申请空间,则自动分配成功,否则分配失败导致栈溢出。连续的一段空间,向低地址扩展,最大容量限定好的 申请效率高,程序员无法控制

# heap

堆保存函数内部动态分配的内存,更准确的说是保存程序的动态变量.
堆是程序员主动申请的 堆在内存中呈现的方式类似于链表(记录空闲地址空间的链表),在链表上寻找第一个大于申请空间的节点分配给程序,将该节点从链表中删除。大多数系统中该快空间的首地址存放的的是本次分配空间的大小,便于释放,将该块空间上的剩余空间再次连接在空闲链表上。向高地址拓展,且不连续 申请效率低,程序员可控,使用方便但是容易产生碎片

# 以上述代码来讨论栗子

本来说函数中的大部分变量都应该是局部的,但是需要注意几点

    1. 函数内部申请的空间是堆中的
    1. 函数内部的 static 变量是 Data 段的静态区
    1. 常量,如 "sac" 、 1 是放在常量区
更新于

请我喝[茶]~( ̄▽ ̄)~*

Solvarg 微信支付

微信支付

Solvarg 支付宝

支付宝

Solvarg 贝宝

贝宝