关于C/C++内存四区的分析

一、内存四大区

1、我们把程序执行前后的内存分为四个区:

代码区、全局区、栈区、堆区

2、但是有一个疑问,这样分类的意义是什么?

例如:因为我们在实际编程的时候,需要根据不同的功能需求,会声明不同类型的变量(如全局变量,局部变量,全局常量,字符串常量等),它们拥有不同的长度、生命周期释放方式等。这样就需要存放在不同的内存区域,这样就能提高程序运行效率,更加灵活地编程。

二、内存四区的功能

  1. 代码区
    这个区域存放函数体的二进制代码.是由操作系统进行管理的。

  2. 全局区
    全局区主要是用来存放全局变量和静态常量(即使用static关键字定义的变量)(一般会是字符串常量),里面有细分出一个常量区。要注意局部变量和局部常量是不属于这个区域的。
    该区域是在程序结束后由操作系统释放。

    在这里插入图片描述
    如图:全局变量和常量的地址十分相近,都是存放在全局区的,而局部变量的地址也十分相近,但并非在全局区,而是在下面的栈区中。

  3. 栈区
    由编译器自动分配释放,存放函数的形参、局部变量等。当函数执行完毕时自动释放。
    如上图所示的局部变量b和c就是存放在栈区的,这两个变量是定义在main函数的,所以是当整个程序执行完,系统才释放空间。如果是定义在自己声明的其他函数体内,当该函数执行完毕之后其内存即被释放。
    值得一提的是,查看局部变量的地址,这样的操作是不正确的,看下面一段代码和输出:

    在这里插入图片描述
    main函数里面有两句完全相同的输出,但终端输出时缺发现只有第一次输出是正确的,其实是因为a是局部变量,在test函数执行后就会被释放,但是编译器为其保留了一次操作的余地,这次操作之后就会被释放了。所以第二次输出的值是不正确的。

  4. 堆区
    一般由程序员手动分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回收。与栈区最大的区别就是,堆区的变量都是我们自己分配和释放的。在学习C语言的时候我们学习了动态内存分配函数malloc,以及其释放函数free。在C++中,起到相同功能的是函数new和delete,它们具体的用法如下:

int *p=new int(10); //为单个变量申请内存空间,其存放的地址为10
int *p=new int [10]; //为数组申请内存空间,其中指针P指向数组的首地址
delete (p);

运行下面的程序:

#include <iostream>
#include <string>

using namespace std;

int * test_1()
{
    int *p=new int(10);
    return p;
}
int * test_2()
{
    int *array=new int[10];
    for(int i=0;i<10;i++)
    {
        array[i]=i;
    }
    return array;
}
int main()
{
   int *p=test_1();
   int *array=test_2();
    cout<<"a的值为:"<<*p<<endl;
    cout<<"a的值为:"<<*p<<endl;
    delete(p);
    cout<<"a的值为:"<<*p<<endl;
    for(int i=0;i<10;i++)
    {
        cout<<"数组的第"<<i<<"个元素的值为:"<<array[i]<<endl;
        cout<<"数组的第"<<i<<"个元素的值为:"<<array[i]<<endl;
    }
    delete(array);
    for(int i=0;i<10;i++)
    {
        cout<<"数组的第"<<i<<"个元素的值为:"<<array[i]<<endl;
        
    }

    system("pause");
}

显然,使用new为局部变量申请地址之后,即使重复访问地址,变量的值也不会丢失,就是因为使用new申请的变量地址存放到堆区了。再使用delete函数释放了变量的内存空间,所以再次访问时发现变量的值已丢失。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值