C++内存分配规则

#include <iostream>
#include <string.h>

using namespace std;

// 程序的内存地址的划分
// 1. 操作系统位数不同,地址划分也会存在一定的差别。但是有一些核心区域是固定的

// 内存区域划分:

    // 保留区:0开始,C库函数(不能变动)

    // 代码区: 一个程序执行的时候,会按照次序依次从代码区调用程序运行(也是不可修改的)

    // 全局变量区: 包括两个部分:.data (非0值)、.bss(未初始化的值)
        // 静态局部变量
        // 静态全局变量
    // 堆区和栈区是可以进行修改的
    // 堆区(地址从低到高):
        // new 分配: 每次申请的时候,会从已释放的内存快中申请可用的,也有可能按照次序往下去执行(做内存池的时候,需要考虑的内容)
        // delete 释放:不会将快内存空间进行擦除,而是将分配的空间标注为已释放。
        // 堆区的内存空间分配之后,若没有主动删除,不会一直占用。因为进程一旦退出,那么所占用的内存就会变得毫无意义
        // 指针指向的地址并不是实际物理内存的空间地址,而是一个虚拟地址。当进程退出的时候,将指针和内存地址之间的联系之间砍掉,那这一部分的内存空间其他进行就可以使用了
    // 栈区(地址从高到低):内存从高往低进行分配
            // (当栈区和堆区内存汇合的时候,程序内存使用完全,没有多余内存可以分配。 但是在一些新的操作系统上,可能会将这一机制进行改善,利用分块技术来避免这一现象产生)
            // 是{} 内定义的变量,出了 {} 程序会自动进行清理
    // 命令行参数环境变量:程序运行的时候,会加载一部分命令行参数,因此,在程序运行的过程中,修改环境变量是不能产生作用的
    // 内核空间:程序运行的时候,会将一部分内存空间分配给内核空间,调度进程的操作系统部分来操作硬件(window下一般是2G,Linux 1G)


// 整个代码以初始化分配的内存空间为准。后面更改则不会更改内存地址
int g1;         // .bss 未被初始化
int g2 = 0;     

// 在一块内存
int g3 = 20;    // .data(非0值) 初始化
int g4 = 40;    // .data (非0值)初始化

static int g6;
static int g7 = 200;

void test01(){

    // s
    int arr1[10]; // 变量内部存放的值是不确定的,因为变量是存放在栈空间的,而出栈和入栈的操作,不会将内存释放掉。因此在重新入栈变量的时候,不确定是上次赋值的哪一块儿区域,值页不确定
    memset(arr1, 0, sizeof(arr1));  // 置为0


    // int arr1[10] = {0};         // 全部设置为0
    char str1[] = "tets01";         // 将  “test01” 的内存空间赋值到 str1(多一个字节\0)


    // 在栈空间中,数组的分配大小不能使用动态产生
    // 在堆空间中,数组的大小分配是可以动态产生,(也就是可以使用变量来指定变量个数)

    // 当一个指针指向的是堆内存空间大小的时候,使用 sizeof 获取的是指针的大小
    // 当一个指针指向的是栈内存空间大小的时候,使用 sizeof 获取的是指向的数据内存大小


}

int main(int argc, char ** argv){

    static int mg1 = 20;

    cout << "代码区: main() 的地址: "  << main << endl; // 输出为 1 ?
    // test01();

    cout << "&g1 =  " << &g1 << endl;
    cout << "g2 = 0==> &g2 = " << &g2 << endl;
    cout << "g3 = 20 ==> &g3 =  " << &g3 << endl;
    cout << "g4 = 40 ==> &g4 =  " << &g4 << endl;

    // 代码区: main() 的地址: 1
    // &g1 =  0x5629b5c59134
    // g2 = 0==> &g2 = 0x5629b5c59138
    // g3 = 20 ==> &g3 =  0x5629b5c59010        (和前面的两个地址并不连续,跳转到另外一块区域)
    // g4 = 40 ==> &g4 =  0x5629b5c59014        (和上面的地址是连续的)


    g1 = 20;
    cout << "&g1 =  " << &g1 << endl;                // &g1 =  0x5629b5c59134  没有发生改变  
    cout << "g2 = 0==> &g2 = " << &g2 << endl;
    cout << "g3 = 20 ==> &g3 =  " << &g3 << endl;
    cout << "g4 = 40 ==> &g4 =  " << &g4 << endl;


    cout << "static int g6; ==> &g6 =  " << &g6 << endl;                // 和全局变量区是存在在一块的
    cout << "static int g7 = 200; ==> &g7 =  " << &g7 << endl;
    cout << "static int mg1 = 20;; ==> &mg1 =  " << &mg1 << endl;       // 和全局变量区是存放在一起的

    // 代码区: main() 的地址: 1
    // &g1 =  0x55b2c4a81134
    // g2 = 0==> &g2 = 0x55b2c4a81138
    // g3 = 20 ==> &g3 =  0x55b2c4a81010
    // g4 = 40 ==> &g4 =  0x55b2c4a81014
    // &g1 =  0x55b2c4a81134
    // g2 = 0==> &g2 = 0x55b2c4a81138
    // g3 = 20 ==> &g3 =  0x55b2c4a81010
    // g4 = 40 ==> &g4 =  0x55b2c4a81014
    // static int g6; ==> &g6 =  0x55b2c4a81140
    // static int g7 = 200; ==> &g7 =  0x55b2c4a81018
    // static int mg1 = 20;; ==> &mg1 =  0x55b2c4a8101c


    // 堆和栈的地址空间
    int *p1 = new int;
    int *p2 = new int;

    cout << "堆 p1 = " << p1 << endl;
    cout << "堆 p2 = " << p2 << endl;
    cout << "栈指针变量 p1 = " << &p1 << endl;  // int* 为数据类型 所以 p1 p2 也是栈内存分配的,只是指向的是堆内存空间
    cout << "栈指针变量 p2 = " << &p2 << endl;

    int i1 = 20;
    int i2 = 30;
    cout << "栈 i1 = " << &i1 <<endl;
    cout << "栈 i2 = " << &i2 <<endl;

    // 堆 p1 = 0x556af8ff1280
    // 堆 p2 = 0x556af8ff12a0
    // 栈指针变量 p1 = 0x7ffdcd51af78
    // 栈指针变量 p2 = 0x7ffdcd51af80
    // 栈 i1 = 0x7ffdcd51af70
    // 栈 i2 = 0x7ffdcd51af74

    int arr1[10] = {0};
    int* pArr1 = new int[20];

    cout << "pArr1 = " << sizeof(pArr1) << endl;    // 指针的大小, 因此需要乘以数组的个数
    cout << "arr1 = " << sizeof(arr1) << endl;    // 所指向的栈空间的大小


    delete[] pArr1;
    pArr1 = nullptr;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值