C++学习笔记(一)——程序的内存模型内存四区

Posted by ThreeStones Blog on July 10, 2023

[TOC]

一、前言

越来越意识到自己应该系统学一门严谨语言的重要性,不管是为了后面找工作,还是读研的需求,我都觉得学习c++是不可缺少的,所以我觉得自己是时候付出行动了,先从B站黑马程序员开始学,事实上已经学过c语言了,所以打算跳过前面的c语言部分。从P84——程序内存模型开始重拾c++,本系列文章主要作为个人笔记。

二、程序的内存模型分区

c++程序在执行时,会将内存大致分为四个区域

(1)代码区:存放函数体的二进制代码,由操作系统管理;

(2)全局区:存放全局变量、静态变量、以及常量;

(3)栈区:由编译器自动分配释放、存放函数的参数值、局部变量等;

(4)堆区:由程序员分配释放、若程序员不释放、程序结束时由操作系统回收;

内存四区的意义:不同区域存放的数据,赋予不同的生命周期,可以更灵活的编程。

2.1.程序运行前

在程序编译后,生成exe可执行程序,未执行该程序前分为两个区域,分别为代码区和全局区。

代码区:存放CPU执行的机器指令

​ 代码区是共享的,共享的目的是对于重复执行的程序,内存只需要存放一份代码即可

​ 代码区是只读的,防止程序意外修改它的指令

全局区:全局变量和静态变量存放于此,全局区还存放了常量,包括字符型常量和其他常量例如const修饰的变量,该区域的数据在程序结束后,由操作系统释放。

具体来看有如下示意图:

全局区与非全局区

代码验证:

#include <iostream>
using namespace std;

// 全局变量
int g_a = 10;

// 全局常量
const int c_g_a = 10;

int main(){

    //局部变量
    int a = 10;
    
    // 局部常量
    const int c_a = 10;

    // 静态变量
    static int s_a = 10;

    cout << "局部变量a的地址:" << (long long)&a << endl;
    cout << "局部常量c_a的地址:" << (long long)&c_a << endl;

    cout << "全局变量g_a的地址:" << (long long)&g_a << endl;
    cout << "全局常量c_g_a的地址:" << (long long)&c_g_a << endl;
    cout << "字符串常量hello world的地址" << (long long)&"hello world" << endl;
    cout << "静态变量s_a的地址" << (long long)&s_a << endl;
    
    return 0;
}

输出:

局部变量a的地址:6422044
局部常量c_a的地址:6422040
全局变量g_a的地址:4206608
全局常量c_g_a的地址:4210692
字符串常量hello world的地址4210800
静态变量s_a的地址4206612

可以看到==局部变量和局部常量在一个区,全局变量、全局常量、字符串常量、静态变量在一个区也即全局区==。

2.2.程序运行后