C++深入浅出讲解内存四区与new关键字的使用

目录
  • 写在前面
  • 内存四区
  • 程序运行前
    • 代码区
    • 全局区
  • 程序运行后
    • 栈区
    • 堆区
  • new关键字
    • new的基本语法
    • 利用new开辟数组

写在前面

从本文开始我就要日常更新C++入门博文啦,从核心编程开始,之前的一些基础我就不再从零整理了,只有函数传参、结构体、指针、数组等稍微难理解的知识在之前的博文写的比较全面;因为竞争确实很大,其他人总结的也很好,要看更详细的基础就看本站的技能树,非常全面;我写博客的初衷一是可以记录自己的学习,加以巩固;二是给更多的人更容易的讲解来快速入门C++,C/C++永不过时!!!

内存四区

下文有内存四区的详细介绍及作用

内存四区的意义:不同区域存放的数据赋予不同的生命周期,让我们的编程方式更灵活。

程序运行前

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

代码区

作用:

存放CPU执行的机器指令(二进制代码,由操作系统进行管理)

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

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

全局区

全局变量和静态常量存放在此

全局区还包含了常量区,字符串常量和其他常量也存放在此

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

代码示例:

#include<iostream>
using namespace std;
//全局变量
int g_a = 10;
int g_b = 10;
const int c_g_a=10;
const int c_g_b=10;
int main()
{
	//创建普通局部变量
	int a = 10;
	int b = 10;
	cout << "局部变量a的地址为:" << (int)& a << endl;
	cout << "局部变量b的地址为:" << (int)& b << endl;
	int c_l_a = 10;
	int c_l_b = 10;
	cout << "局部常量c_l_a的地址为:" << (int)&c_l_a << endl;
	cout << "局部变量c_l_b的地址为:" << (int)&c_l_b << endl;
	cout << "全局变量g_a的地址为:" << (int)&g_a << endl;
	cout << "全局变量g_b的地址为:" << (int)&g_b << endl;
	//静态变量
	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 World" << endl;
	//const 修饰的变量
	//const 修饰的全局变量、const修饰的局部变量
	cout << "全局常量c_g_a的地址为:" << (int)&c_g_a << endl;
	cout << "全局常量c_g_b的地址为:" << (int)&c_g_b << endl;
}

各变量地址的关系:

从运行效果可以清楚的看到带全局的变量地址所占空间相近,而局部的地址相差就比较远了,看下我做的图示总结:

程序运行后

栈区

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

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

#include<iostream>
using namespace std;
int* func1(int b)//返回值类型为 int *,所以return一个地址才合法
{//形参数据也会开辟到栈区
	b = 100;
	int a = 10;//局部变量,存放在栈区,栈区的数据在函数执行完成后自动释放
	return &a;//返回局部变量的地址
}
int main()
{
	//接受func1函数的返回值
	int* p = func1(10);
	cout << *p << endl;//第一次数据正常,因为编译器会自动保留
	cout << *p << endl;//第二次往后是随机数,该地址被释放
	cout << *p << endl;
}

tips:这里输出只有一个10,剩下输出结果无法猜测,因为返回的地址已经被编译器释放掉

堆区

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

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

示例:

int * func()
{
	//利用new 关键字把栈开辟到堆区
	//指针 *p实质上也是栈区数据,指针保存的数据放到堆区
	int* p = new int (10);
	return p;
}
int main()
{
	int* a = func();
	cout << *a << endl;//无论输出多少次,都能输出a的值
	cout << *a << endl;
	cout << *a << endl;
}

这里不同于栈区的时,无论输出多少次*a,都是结果十,下面来张图助理解:

主函数中用*a作为*p的返回值,a的地址为0x0011,保存的数据为10,这是数据保存在堆中,除非程序结束,该地址都不会被释放。

new关键字

new的基本语法

开辟:

数据类型 + 指针变量 = new +相同数据类型 +(赋值)

这样可在堆区开辟数据,作为栈区函数返回值也不会被编译器自动释放

删除:

delete 变量地址

堆区数据由管理员开辟或释放,如果想要释放数据就利用delete关键字

利用new开辟数组

示例:int* Array = new int[n]; 和基本语法相比就是()变成了[],并且里面可以存放常量或者变量,当我们想控制数组长度的时候,这也是自定义的一种方法。让 n 等于10,那么数组Array[]的长度为十,我们可以用随机数来给数组赋值。释放数组也是利用delete关键字,例如 delete[] Array; 删除数组加[]放在数组名前。

例如:

void test02(int *Array)
{
	srand((unsigned int)time(NULL));
	for (int i = 0; i < 10; i++)
	{
		Array[i] = rand() % 20 + 1;
	}
	for (int i = 0; i < 10; i++)
	{
		cout << Array[i] << "  ";
	}
}
int main()
{
    int *Array = new int [10];
    test02(Array);
}

附带个运行图:

到此这篇关于C++深入浅出讲解内存四区与new关键字的使用的文章就介绍到这了,更多相关C++内存四区内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 分享C++三种类型new类型的运算符使用详情

    目录 1.new操作符 2.::operator new 2.1原始调用 2.2重载1 2.3重载2 3.place new 1.new操作符 new operator,平时用的最多的new操作符,其对应delete operator,不能被重载,其包含两个操作(既申请空间,又调用构造函数) (1)使用::operator new申请内存 (2)调用类的构造函数 class CTestUse { public:     CTestUse() { cout << __FUNCTION__ <

  • C++内存四区之代码区、全局区、栈区和堆区

    C++内存四区 C++ 在程序执行时,将内存大致分为代码区,全局区,栈区和堆区四个区域.不同的区域存储不同的数据,赋予不同的生命周期,能够更灵活地进行编程. 代码区:存放函数体的二进制代码,由操作系统管理创建,代码区时共享的,对于频繁被执行的程序,只需要存有一份代码即可: 全局区:存放全局变量和静态变量以及常量,在程序结束后由操作系统释放: 栈区:由编译其自动分配释放,存放函数的参数值以及局部变量等: 堆区:一般由程序员通过 new 开辟空间,进行分配和释放,若程序员不释放,则程序结束时由操作系

  • 浅析C++ new的三种面貌

    1.new的三种面貌 C++中使用new运算符产生一个存在于Heap(堆)上对象时,实际上调用了operator new()函数和placement new()函数.在使用new创建堆对象时,我们要清楚认清楚new的三种面貌,分别是:new operator.operator new()和placement new(). 1.1new operator new operator是C++保留的关键字,我们无法改变其含义,但我们可以改变new完成它功能时调用的两个函数,operator new()和

  • C++深入浅出讲解内存四区与new关键字的使用

    目录 写在前面 内存四区 程序运行前 代码区 全局区 程序运行后 栈区 堆区 new关键字 new的基本语法 利用new开辟数组 写在前面 从本文开始我就要日常更新C++入门博文啦,从核心编程开始,之前的一些基础我就不再从零整理了,只有函数传参.结构体.指针.数组等稍微难理解的知识在之前的博文写的比较全面:因为竞争确实很大,其他人总结的也很好,要看更详细的基础就看本站的技能树,非常全面:我写博客的初衷一是可以记录自己的学习,加以巩固:二是给更多的人更容易的讲解来快速入门C++,C/C++永不过时

  • 详解C语言中的内存四区模型及结构体对内存的使用

    内存四区 1.代码区 代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的. 2.静态区 所有的全局变量以及程序中的静态变量都存储到静态区. 3.栈区 栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出.对于自动变量,什么时候入栈,什么时候出栈,是不需要程序控制的,由C语言编译器.实现栈不会很大,一般都是以K为单位的. 当栈空间以满,但还往栈

  • 深入浅出讲解Java集合之Collection接口

    目录 一.集合框架的概述 二.集合框架(Java集合可分为Collection 和 Map 两种体系) 三.Collection接口中的方法的使用 四.集合元素的遍历操作 A. 使用(迭代器)Iterator接口 B. jdk5.0新增foreach循环,用于遍历集合.数组 五.Collection子接口之一:List接口 List接口方法 ArrayList的源码分析: JDK 7情况下: JDK 8中ArrayList的变化: LinkedList的源码分析: Vector的源码分析: 六.

  • Java深入浅出讲解多线程的概念到使用

    目录 1.线程的几个相关概念 2.线程的状态与生命周期 3.线程的优先级与调度 4.Java中多线程的创建 4.1继承Thread类创建线程 4.2实现Runnable接口创建线程 5.多线程的同步控制 6.线程之间的通信 下面开始学习Java多线程吧! 写在前面:Java系统在语言层次上对多线程直接提供支持,多线程的主要目的是将一个程序中的各个程序段并发化,在在通常情况下,Java程序各部分是按顺序一次执行的,由于某种原因,需要将这些按顺序执行的程序段转化为并发执行,每个程序段在逻辑上是相互完

  • 深入浅出讲解Java集合之Map接口

    目录 一.Map接口继承树 二.Map接口中的常用方法 三.源码分析 1. HashMap的底层实现原理? 2.LinkedHashMap的底层实现原理(了解) 四.Collections工具类 一.Map接口继承树 Map:双列数据,存储key-value对的数据 ---类似于高中的函数:y = f(x) A.HashMap:作为Map的主要实现类:线程不安全的,效率高:存储null的key和value a.LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历. 原因

  • 深入浅出讲解Spring框架中依赖注入与控制反转及应用

    目录 一. 概念: 1. 使用前: 2. 使用后: 二. 理解控制反转(Ioc): 三. IoC的应用方法 一. 概念: 依赖注入(Dependency Injection,DI)与控制反转(IoC)的含义相同,只不过是从两个角度描述的同一个概念.对于一个Spring初学者来说,这两种称呼都很难理解,我们通过简单的语言来描述这两个概念. 使用对比: 1. 使用前: 当某个Java对象(调用者)需要调用另一个Java对象(被调用者,就是被依赖对象)时,在传统模式下,调用者通常会采用"new被调用者

  • Java 深入浅出讲解代理模式

    目录 1.动态代理模式 2.JDK动态代理 3.JDK动态代理代码演示 1.动态代理模式 动态代理的特点: 当代理对象的时候,不需要实现接口 代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型) 动态代理的别称:JDK代理.接口代理 2.JDK动态代理 类图: Java动态代理类位于java.lang.reflect包下 一般主要涉及到以下两个类: 1.Interface InvocationHandler : 该接口中仅定义了一

  • Java 深入浅出讲解泛型与包装类

    目录 1.什么是泛型 2.泛型的语法 3.泛型的上界 4.通配符 (1)通配符的上界 (2)通配符的下界 5.包装类 1.什么是泛型 泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型). 先看以下的例子: 我们以前学过的数组,只能存放指定类型的元素.如:int[] array=new int[10];String[] array=new String[10];而Object类是所有类的父类,那么我们是否可以创建Obj数组呢? class Mya

  • C语言深入浅出讲解顺序表的实现

    目录 1.线性表 2.顺序表 2.1 概念及结构 2.2 提供接口 2.3 接口实现 今天起开始编写数据结构中的各种数据结构及算法的实现,说到顺序表,我们首先得了解下线性表. 1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列. 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表.链表.栈.队列.字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线.但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储. 2.顺序表

随机推荐