C++程序在执行时,将内存大方向分为 4 个区域,不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程

  • 代码区:存放函数二进制代码,由操作系统进行管理

  • 全局区:存放全局变量和静态数据以及常量,程序运行结束,由操作系统释放

  • 堆区:由程序员自动分配和释放,若程序员不释放,程序结束时由操作系统回收

  • 栈区:由编译器自动分配释放,存放函数内部局部变量,函数的参数等

1.1  程序运行前

在程序编译后,生成了exe可执行文件,未执行前分为 2 个区域

(1)代码区:存放 CPU 的机器指令

  特点

  • 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中由一份代码即可

  • 代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

(2)全局区:全局变量和静态变量存,还包含了常量区,字符串常量和其他常量也存放在此

  特点:该区域的数据在程序结束后由操作系统释放

include <iostream>
using namespace std; //全局变量
int g_a =10;
int g_b =10; //const修饰的全局常量
const int c_g_a =10; int main()
{
//全局区
//创建普通局部变量
int a = 10;
int b = 10; cout << "局部变量a的地址" <<(int) &a <<endl;
cout << "局部变量b的地址" <<(int) &b <<endl;
cout << "全局变量g_a的地址" <<(int) &g_a <<endl;
cout << "全局变量g_b的地址" <<(int) &g_b <<endl; //静态变量,在前面加关键字static
static int s_a =10;
static int s_b =10;
cout << "静态变量s_a的地址" <<(int) &s_a <<endl;
cout << "静态变量s_b的地址" <<(int) &s_b <<endl; //常量
//字符串常量
cout <<"字符串常量的地址" << (int)&"hello" << endl; //const修饰的全局常量
cout << "全局常量 c_g_a的地址:" << (int)&c_g_a << endl; //局部常量
const int c_l_a=10;
cout << "局部常量 c_l_a的地址:" << (int)&c_l_a << endl; //比较这些的地址发现:局部变量、const修饰的局部变量不在全局区中 system("pause");
return 0;
}

全局区与不在全局区的区别

注:常量区中存放 const 修饰的全局变量字符串变量

1.2  栈区

注意事项:

  • 栈区数据不要返回局部变量的地址,栈区的数据由编译器管理开辟和释放。

  • 函数的形参也是局部变量。

#include <iostream>
using namespace std; int* func() //形参数据也会放在栈区
{
int a=10;局部变量,放在栈区,栈区的数据在函数执行后自动释放
return &a; //返回局部变量地址
} int main()
{
int *p = func();
cout << *p <<endl; //第一次打印正确数据,由于编译器做了保留
cout << *p <<endl; //第二次这个数据就不再保留 system("pause");
return 0;
}

为什么栈区数据不返回局部变量的地址??

1.3  堆区

在C++中主要利用new在堆区中开辟数据

#include <iostream>
using namespace std; int * func()
{
//指针本质也是局部变量,放在栈上,指针保存的数据放在了堆区
int *p = new int (10); //用new关键字,可以将数据开辟到堆区
return *p;
} int main()
{
int *p=func(); cout<< *p <<endl;
system("pause");
return 0;
}

1.4  new和delete操作符

C++通过new和delete实现动态内存的申请和释放------->可以在一个函数申请,另一个函数释放

#include <iostream>
using namespace std; int * func()
{
//在堆区创建整形数据
//new返回是---->该数据类型的指针
int *p= new int (10);
return p;
} void test()
{
int *p=func();
cout << *p <<endl;
//堆区的数据,由程序员开辟
//由程序员释放,如果想释放堆区的数据,利用关键字delete
delete p;
cout << *p <<endl; //内存已经被释放,再次访问就是非法,会报错
} //利用new在堆区开辟数组
void test1()
{
//在堆区,创建10整型数据的数组
int *arr = new int [10]; //10代表数组中有10个元素 for(int i=0;i<10;i++)
{
arr[i] = i + 100 ;
}
for(int i=0;i<10;i++)
{
cout <<arr[i] << endl ;
}
//释放数组的时候,要加 [ ] 才可以
delete[] arr;
} int main()
{
test();
test1(); system("pause");
return 0;
}

new 和 delete

1.  new运算符:

  按指定类型和大小在堆区动态的分配内存,如果创建成功则返回这块内存空间的首地址,否则返回NULL

语法:指针变量名=new 类型名 (初值列表)

  • 创建动态同类型的多个对象:指针变量名=new 类型名[下标表达式]

  • 使用new也可以创建多维数组:new 类型名[下标表达式1] [下标表达式...]

注:下标表达式1可以是任意正整数的表达式,其他下标必须是正整数常量表达式

2.  delete运算符:

  释放空间

语法:delete 指针变量名

删除动态数组:delete[ ]  指针变量名 ------>  [  ]表示释放为多个对象分配的地址,无需说明要释放对象个数

1. 内存分区模型以及new、delete操作的更多相关文章

  1. 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  2. 分布式缓存技术redis学习(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  3. 分布式缓存技术redis系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  4. C/C++内存分区

    C/C++编译的程序占用的内存分区 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数名,局部变量的名等.其操作方式类似于数据结构中的栈. 2.堆区(heap)— 由程序员分配释放, 若 ...

  5. redis高级应用(集群搭建、集群分区原理、集群操作)

    文章主目录 Redis集群简介 Redis集群搭建 Redis集群分区原理 集群操作 参考文档 本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 ...

  6. 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性

    基于.net的分布式系统限流组件   在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...

  7. redis系列之4----redis高级应用(集群搭建、集群分区原理、集群操作)

    文章主目录 Redis集群简介 Redis集群搭建 Redis集群分区原理 集群操作 参考文档 本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 ...

  8. JVM内存区域模型

    一:Java技术体系模块图 二:JVM内存区域模型 1.方法区 也称"永久代” .“非堆” ,"perm",  它用于存储虚拟机加载的类信息.常量.静态变量.是各个线程共 ...

  9. jvm性能优化及内存分区

     jvm性能优化及内存分区 2012-09-17 15:51:37 分类: Java Some of the default values for Sun JVMs are listed below. ...

随机推荐

  1. 第7.9节 案例详解:Python类封装

    上节介绍了Python中类的封装机制,本节结合一个具体例子进行详细说明. 我们定义一个Person类,其内部有姓名.年龄和类型三个实例变量,并定义了相关的存取方法: class Person():   ...

  2. 第15.41节、PyQt(Python+Qt)入门学习:输入部件QComboBox组合框功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 Designer中输入工具部件中的Combo Box组合框与 ...

  3. 第十一章、Designer中主窗口QMainWindow类

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 主窗口对象是在新建窗口对象时,选择main window类型的模板时创建的窗口对象,如图: ...

  4. 爬虫模块-requests

    title: python爬虫01 date: 2020-03-08 22:56:12 tags: 1.requests模块 requests模块的底层是urllib,但是比urllib更强大也更加简 ...

  5. AcWing 369. 北大ACM队的远足

    \(\text{Update on 2020.3.25}\) 我之前的做法也有问题,讨论还是不够严谨,导致又有几组(见 打卡评论区)\(\text{Hack}\) 此题数据极水,这里有几种错误写法: ...

  6. mysql 迁移数据库到 oracle (sql注意问题)

    http://ykdn2010.iteye.com/blog/1511349 一. 项目已用到 oracle 函数的转换 1.  Oracle 中的 TO_DATE (),TO_CHAR () 示例: ...

  7. 通过游戏学javascript系列第一节Canvas游戏开发基础

    本节教程通过一个简单的游戏小例子,讲解Canvas的基础知识. 最终效果: 点击移动的方块,方块上的分数会增加,方块的行进方向会改变,并且方块的速度会增加. 在线演示 源码 HTML5引入了canva ...

  8. SpringBoot集成基于tobato的fastdfs-client实现文件上传下载和删除

    1. 简介   基于tobato的fastdfs-client是一个功能完善的FastDFS客户端工具,它是在FastDFS作者YuQing发布的客户端基础上进行了大量的重构,提供了上传.下载.删除. ...

  9. ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件

    前言 随着Asp .Net Core的升级迭代,很多开发者都逐渐倾向于.net core开发. .net core是一个跨平台的应用程序,可以在windows.Linux.macOS系统上进行开发和部 ...

  10. 自顶向下redis4.0(5)持久化

    redis4.0的持久化 目录 redis4.0的持久化 简介 正文 rdb持久化 save命令 bgsave命令 rdb定期保存数据 进程结束保存数据 aof持久化 数据缓冲区 刷新数据到磁盘 ap ...