1、内存分区模型

C++程序在执行时,将内存大方向划分为4个区域

  代码区:存放函数体的二进制代码,由操作系统进行管理(写的所有代码都在代码区)

  全局区:存放全局变量、静态变量以及常量

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

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

  内存四区的意义:不同区域的数据,赋予不同的生命周期,给我们更大的灵活编程

程序运行前:

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

代码区:

    存放CPU执行的机器指令

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

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

全局区:

    全局变量(main函数外面)和静态变量(在普通变量前加static)存放于此

    全局区还包含了常量区,字符串常量 ("hello world") 和其他常量(const修饰的全局变量)也存放于此

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

  总结:

      C++中在程序运行前分为全局区和代码区

      代码区特点是共享和只读

      全局区中存放全局变量、静态变量、常量

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

程序运行后:

栈   区:

    由编译器自动分配释放,存放函数的参数值,局部变量等

    注意:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放

#include<iostream>
using namespace std; //栈区数据注意事项 --- 不要返回局部变量的地址
//栈区的数据由编译器管理开辟和释放 int * func(int b) //形参数据也会放在栈区
{
   b = 100;
   cout << b << endl;
int a = 10; //局部变量 存放栈区,栈区的数据在函数执行完后自动释放
return &a; //返回局部变量的地址
} int main()
{
//接收函数的返回值
int * p = func(1); cout << *p << endl; //第一次可以打印出正确的数据 10 ,是因为编译器防止用户是误操作而做了一次保留
cout << *p << endl; //第二次这个数据就不再保留 打印出来的是乱码 因为局部变量a的内存已经被释放 system("pause");
return 0;
}

    打印出来的结果:

堆   区:

    由程序员分配释放,若程序员不释放,程序结束时由操作系统回收

    在C++中主要利用new在堆区开辟内存 

    实例: 

#include<iostream>
using namespace std; int * func()
{
//利用new关键字 可以将数据开辟到堆区
   //指针 本质也是局部变量,放在栈上。指针保存的数据是放在堆区

int * p = new int (10);
return p;
} int main()
{
int * p = func(); //接收函数的返回值 cout << *p << endl;
cout << *p << endl;
system("pause");
return 0;
}

    打印结果:

new操作符

  C++中利用new操作符在堆区开辟数据

  堆区开辟的数据,由程序员手动开辟,手动释放,释放操作符delete

  语法:new 数据类型

  利用new创建的数据,会返回该数据对应的类型的指针

  实例:1、基本语法

#include<iostream>
using namespace std; int * func()
{
//在堆区创建整型数据
//new返回的是 该数据类型的指针
int * p = new int (10);
return p;
} void test1() //new的基本语法
{
int * p = func();
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;
//堆区数据由程序员管理开辟、释放,若想释放 利用关键字delete
delete p;
cout << *p << endl; //内存已经被释放,再次访问就是非法操作,会报错
}
int main()
{
//int * p = func(); //接收函数的返回值
test1(); system("pause");
return 0;
}

打印结果:因为delete p 后,p已被释放,故第四次打印出错。

    2、在堆区new数组

#include<iostream>
using namespace std; //2、在堆区利用new开辟数组
void test2()
{
//创建10个 整型数据的数组,在堆区
int * arr = new int[10]; //10代表数组有10个元素
for (int i = 0; i < 10; i++)
{
arr[i] = i + 100; //给10个元素赋值 100~109
}
for (int i = 0; i < 10; i++)
{
cout << arr[i] << endl;
}
//释放堆区数组
//释放数组的时候要加[]才可以
delete[] arr;
}
int main()
{
test2();
system("pause");
return 0;
}

    打印结果:

C++核心编程 1 程序的内存模型的更多相关文章

  1. STM32F4编程手册学习2_内存模型

    STM32F4编程手册学习2_内存模型 1. 内存映射 MCU将资源映射到一段固定的4GB可寻址内存上,如下图所示. 内存映射将内存分为几块区域,每一块区域都有一个定义的内存类型,一些区域还有一些附加 ...

  2. Java并发编程:JMM(Java内存模型)和volatile

    1. 并发编程的3个概念 并发编程时,要想并发程序正确地执行,必须要保证原子性.可见性和有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.1. 原子性 原子性:即一个或多个操作要么全部 ...

  3. Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解

    目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...

  4. JAVA并发编程的艺术 JMM内存模型

    锁的升级和对比 java1.6为了减少获得锁和释放锁带来的性能消耗,引入了"偏向锁"和"轻量级锁". 偏向锁 偏向锁为了解决大部分情况下只有一个线程持有锁的情况 ...

  5. java并发编程(9)内存模型

    JAVA内存模型 在多线程这一系列中,不去探究内存模型的底层 一.什么是内存模型,为什么需要它 在现代多核处理器中,每个处理器都有自己的缓存,定期的与主内存进行协调: 想要确保每个处理器在任意时刻知道 ...

  6. 【Windows核心编程】一个使用内存映射文件进行进程间通信的例子

    进程间通信的方式有很多种,其底层原理使用的都是内存映射文件. 本文实现了Windows核心编程第五版475页上的demo,即使用内存映射文件来在进程间通信. 进程1 按钮[Create  mappin ...

  7. [Windows核心编程]32bit程序在64bit操作系统下处理重定向细节[1]

    这段时间,都在做Ring3层的普通32bit程序兼容64bit操作系统的代码修改,在此记录修改和学习心德.编程领域太广, 任何人经历有限,本人不是专家,所以我一贯原则是: 用到的时候,才去研究,在去记 ...

  8. Windows核心编程 第十七章 -内存映射文件(下)

    17.3 使用内存映射文件 若要使用内存映射文件,必须执行下列操作步骤: 1) 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件. 2) 创建一个文件映射内核对象,告诉系统该 ...

  9. Windows核心编程 第十七章 -内存映射文件(上)

    第1 7章 内存映射文件 对文件进行操作几乎是所有应用程序都必须进行的,并且这常常是人们争论的一个问题.应用程序究竟是应该打开文件,读取文件并关闭文件,还是打开文件,然后使用一种缓冲算法,从文件的各个 ...

随机推荐

  1. WPF路由事件

    ​    这节讲一下WPF中的路由事件(Routed Event). [什么是事件] 在了解路由事件前,我们应先来了解一下什么是事件(Event). 在Windows系统中,像鼠标单击,双击,移动这样 ...

  2. spring之自定义注解

    java.lang.annotation提供了四种元注解,专门注解其他的注解: @Target –注解用于什么地方,默认值为任何元素,表示该注解用于什么地方.可用的ElementType指定参数 ,也 ...

  3. 接口测试进阶接口脚本使用--apipost(预/后执行脚本)

    预执行脚本的作用时间 预执行脚本是一个请求发送前执行的脚本. 预执行脚本的作用 预执行脚本可以完成以下作用: 编写JS函数等实现复杂计算: 变量的打印 定义.获取.删除.清空环境变量 定义.获取.删除 ...

  4. 10个最酷的Linux单行命令

    下面是来自  Commandlinefu 网站由用户投票决出的 10 个最酷的 Linux 单行命令,希望对你有用. sudo !! 以 root 帐户执行上一条命令. python -m Simpl ...

  5. 阿里云服务器部署mongodb

    在阿里云上买了个服务器,部署mongodb遇到一些坑,解决办法也是从网上搜集而来,把零零碎碎的整理记录一下. 服务器是:Alibaba Cloud Linux 下载安装 mongodb官网下载实在是太 ...

  6. BUUCTF-[CISCN2019 华东南赛区]Web4

    BUUCTF-[CISCN2019 华东南赛区]Web4 看题 点击Read somethings,会跳转到 http://3fd8b1f9-614f-47ff-8e79-0f678e7bb4eb.n ...

  7. GUI容器之布局管理器

    布局管理器 布局管理器:frame.setLayout(); 默认值为new flowLayout() 流式布局 frame.setLayout(new FlowLayout(FlowLayout.R ...

  8. Java变量命名规范

    java命名规范 所有方法.变量.类名:见名知意 类成员变量:首字母小写.驼峰原则: 例如:lastName 第一个单词首字母小写,其余首字母大写 局部变量:首字母小写.驼峰原则 类名: 首字母小写. ...

  9. https(ssl) 免费证书

    https://letsencrypt.org/getting-started/ https://certbot.eff.org/lets-encrypt/centosrhel7-nginx http ...

  10. Linux串口调试详解

    测试平台 宿主机平台:Ubuntu 16.04.6 目标机:iMX6ULL 目标机内核:Linux 4.1.15 目标机添加串口设备 一般嵌入式主板的默认镜像可能只配置了调试串口,并用于 consol ...