C/C++中程序数据的分类与内存分布,C++内存管理方式之new / delete 操作符与malloc / free的区别

news2025/1/8 4:09:07

TIPS

  1. const修饰数据类型并不会影响它在内存当中某个区域的存储位置,比方说原先是在栈区上面的,然后用const修饰了一下,并不就是说你现在已经变到静态区里面去了,你还是在栈上面
  2. 指针与指针之间的等号赋值也需要考虑到权限的放大与缩小问题,bty,地址等于指针。也就是说从右往左的过程当中,权限只能够平移或者缩小,权限不能够放大。

C/C++中程序数据的分类与内存分布

在这里插入图片描述

  1. 在程序当中需要存储一些数据,然后数据的分类有局部数据,还有就是静态数据和全局数据,他们的特点就是生命周期在全局可以一直用,还有常量数据和动态申请的数据。
  2. 在平时写程序的过程当中,局部数据用的最多,比如说在当前函数当中去创建各种各样的变量,所以说局部数据通常就是在函数里面定义的各种局部变量,他就是跟着函数走,本质上就是存储在函数调用的时候开辟的函数栈帧里面;静态数据与全局数据的话,他们的生命周期就是整个程序存在的时间;常量数据就是不能够去修改的,比如常量字符串等等;然后动态申请的数据基本上在数据结构当中用的会比较多一点.
  3. 然后一般我们在编译器上写程序的话,***我们写的这些代码实际上都是在磁盘里面,因为相当于我们是在文件里面去写代码,所以说我们写的这些东西是在磁盘文件里面,然后对于写的这些代码进行编译加链接,就会生成一个可执行程序,这个可执行程序也是以一个磁盘文件的形式存在于磁盘里面。***然后接下来我们把这个可执行程序给他运行起来,运行起来的本质就是以一个进程的角度在操作系统之上进行运行。
  4. 然后这个可执行程序里面都是一些计算机能够看懂的二进制指令,当然还有一些数据。然后当这个可执行程序运行起来以后,也就是载入到内存当中,这个被可执行程序exe使用的内存区域每个进程呢都把它叫做虚拟进程地址空间。这个进程地址空间就需要对不同数据进行存储,因此就会内部划分区域。最上面的话是高地址,主要是给操作系统的内核用的;然后接下来就是几个熟悉的区域:栈,堆,静态区/数据段,常量区/代码段。
  5. 然后对于局部数据而言,一般都是存在栈上面,比方说要去调用一个函数,那么就会去建立函数栈帧,建立函数栈帧最本质的一个要点就在于需要去存储局部数据。然后到函数结束的时候,函数栈帧销毁,那么里面的这些局部数据也就会一起去销毁。其实局部数据的感觉就有点类似于一次性的那种感觉,就是短期用用的。对于栈区的话还有一个作用就是方便我们去进行递归就是不断的去建立函数栈帧,然后再进行销毁,然后再进行空间的复用(比如说二叉树)
  6. 但有时候的话也需要用一些静态数据全局数据,也就是说随着时间的推移,要能够保持一定的连续性,这些数据的话它不能够存在栈区里面,所以说就需要单独去找一个区域给他存起来,所以说,就在静态区/数据段这个地方把这些数据给他存起来,然后这些数据的话,在整个程序在的时候,他都也都是在的,不是说函数结束它就销毁了。
  7. 然后对于一些常量以及在可执行程序当中的一些指令的话,都是放在常量区/代码段的
  8. 然后还有一些数据,比方是需要程序员他自己要去动态开辟的,并且是自己申请自己释放空间,相当于就是说是自主权比较大一点,对于这种动态申请的数据,它就是放在堆上面
  9. 然后为什么要划分成这么多的区域?主要就是因为我们的程序有很多需求.
    10.在这里插入图片描述
    在这里插入图片描述

经典检测

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
static int staticVar = 1;
int localVar = 1;
int num1[10] = { 1, 2, 3, 4 };
char char2[] = "abcd";
const char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof(int) * 4);
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
free(ptr1);
free(ptr3);
}

在这里插入图片描述

  1. 这个肯定是个全局变量,全局变量是放在静态区的C
  2. 这个也是一个静态变量,那么他想当然肯定也是放在静态区的C
  3. 这个也是一个静态变量,那么他想当然肯定也是放在静态区的C
  4. 这个的话相当于是一个函数里面的局部变量而已,肯定是在内存栈区里面A
  5. 这个也是一个函数里面的一个数组而已,在函数栈帧里面,所以说也是在内存栈区里面A
    在这里插入图片描述
  6. 这是一个在函数里面的一个数组而已,那么肯定也是在函数栈帧里面,肯定是在内存栈区里面A
  7. 这个char2是一个数组的名字,这就是数组首元素的地址,然后相当于是对数组首元素的地址进行解引用,那不就是相当于是在访问处于内存栈区的数组元素吗?所以说访问出来的东西还是在内存的栈区里面A
  8. 他其实相当于是一个指针,不过这边需要注意,虽然他是const的修饰,但这并不意味着它是一个静态变量了,不意味着他就跑到静态区里面去了。他无非还就是一个内存栈区里面的普通指针罢了,不过有点类似于常变量的这种感觉。然后这个指针变量里面存放的就是这个字符串常量第一个字符的地址。不过指针变量是在栈区的A
  9. 然后对于这个指针变量pchar进行解引用,首先这个指针变量它指向的是处于内存常量区的字符串常量的第一个字符,那么这样子解引用出来就得到了一个字符,这个字符就是处于内存常量区里面的那个字符,所以在常量区D
  10. ptr1无非就是一个指针而已,肯定是在内存栈区的,不过它指向的那块内存空间是属于内存堆区的罢了A
  11. 然后对这个指针ptr1进行解引用操作,这时候访问到的就是属于内存堆区里面的数据,所以在堆区B
    在这里插入图片描述
  12. sizeof数组名,计算的是整个数组所占内存字节大小,所以是40
  13. 这个与第一个道理是一样的,也是计算整个数组所占内存字节的大小,sizeof是计算进入字符串终止符\0的,所以大小为5
  14. 相当于就是统计字符串的长度,然后碰到\0就会停下来,\0的话是不会统计进去的,所以为4
  15. 这个相当于是在计算一个指针的大小,那这个非常简单,在32位机器下面是四个字节
  16. 这个也是在统计字符串的长度,为4,很简单
  17. 这个也是在计算一个指针的大小,也非常简单,就是四个字节(32位下)

C++内存管理方式之new / delete 操作符

  1. 首先复习回顾C,C的那些动态申请内存的各种方法在cpp当中也是可以去使用的
    在这里插入图片描述
  2. C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
  3. 在这里插入图片描述
  4. 如:用new向内存堆区动态申请一个int类型的空间
    在这里插入图片描述
  5. 如:用new向内存堆区动态申请一个int类型的空间并初始化为522
    在这里插入图片描述
  6. 如:用new向内存堆区动态申请10个int类型的空间
    在这里插入图片描述
  7. 注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],注意:匹配起来使用,如:
    在这里插入图片描述

new/delete 与 malloc/free 区别

  1. 在C++向内存堆区申请与释放空间的话,一般是用new与delete。然而在C的话用malloc/free。
  2. 然后如果向内存堆区申请的,这块空间是给内置类型来用的,其实这两种方法的话,差距并不是很大,甚至说没有。
  3. 真正体现优劣的地方就在于如果说向内存堆区申请的这块空间是给那些自定义类型变量(实例化对象)的,对于malloc/free来讲,他们只会单纯的去开辟一块多少多少大小的空间,然后等会儿把这块空间给他全部释放掉;但对于new与delete,如果 “自定义类型* p = new 自定义类型(构造函数参数)”, 就像这样子相当于在向内存堆区申请空间的同时,还能够直接进行调用构造函数初始化;然后delete p; 在把这块空间释放前会去调用析构函数。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/515362.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用Python程序生成字符画 让男大学生们洗脑的挖呀挖呀挖

源码地址 原教程在这里 演示效果:(有点虚) 利用Python程序生成字符画 让男大学生们洗脑的挖呀挖呀挖 使用教程(源码在文章最后) 打开pyhton编译器安装opencv和Pillow库把要进行字符串化的视频命名为input.mp4&#…

nginx: 配置https证书,wss证书

作用:SSL证书卸载 1、制作证书 openssl genrsa -des3 -out server.key 2048 openssl req -new -key server.key -out server.csr openssl rsa -in server.key -out server.key openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt …

windows 通过bat一键Android手机截图

首先资源需要5积分链接如下: https://download.csdn.net/download/weixin_38287114/87774870?spm1001.2014.3001.5501 使用范围: 有一台电脑是window系统,电脑安装配置了adb 有一台手机,打开了usb调试 你想截图的软件没有usb…

ArrayList 和 LinkedList 之间应该怎么选择?

Joshua Bloch:我写了 LinkedList,但我自己都不用! 对,Joshua Bloch 就是 LinkedList 的作者! 如果你真信了作者的话,那就真的大错特错了,LinkedList 虽然用的没有 ArrayList 多,但使…

高性能存储SIG月度动态:EROFS支持直接索引容器镜像tar包,io_uring将支持并优化NVMe直通

高性能存储 SIG(Special Interest Group)目标:存储领域的发展历程,本质上是存储介质与软件栈相互促进发展的过程。高性能存储 SIG 致力于存储栈性能挖掘,当前主要聚焦内核 io_uring 技术优化异步 IO 性能,使…

bugku——变量1

拿到题目后是一串PHP代码,给到提示是flag在变量中,接下来进行代码审计 error_reporting(0):关闭错误报告 include “flag1.php”:包含flag1.php文件 highlight_file(_file_):页面进行语法高亮显示 isset($_GET[‘args’])&#xf…

AI模型推理(4)—— 认识ServingRuntime

参考: Serving Runtimes - KServe Documentation Website 模型推理服务化:如何基于Triton开发自己的推理引擎? - 知乎 GitHub - openai/triton: Development repository for the Triton language and compiler 前言 ServingRuntime&#…

Qt quick基础3(基础动画,包含旋转动画、串行并行动画及其嵌套)

Qt quick基础3(基础动画) 目录 Qt quick基础3(基础动画)前言前期准备工作Animation on property 元素加载后自动运行动画Behavior on property 当元素值改变后运行动画Standalone Animation 单独动画旋转动画分组动画串行动画并行…

干货 | 科研决策怎么做?四个步骤一招解决!

Hello,大家好! 这里是壹脑云科研圈,我是喵君姐姐~ 又是给大家带来满满干货的一天,今天要给大家介绍的是狐少侠对于科学决策的四个步骤的详细解读! 最近,有读者问了我几个关于决策的问题:要不要…

ubuntu22.04 编译安装 Kate 编辑器

ubuntu22.04 编译安装 Kate 编辑器 文章目录 ubuntu22.04 编译安装 Kate 编辑器0x0 目的0x1 在 Ubuntu 22.04 编译安装 Kate0x11 Download dependencies0x12 Build kate and kwrite0x13 Setup paths for binary and shared libraries0x14 Misc trials 0x2 配置 Kate渲染空白字符…

R语言 | 数据分析与处理

目录 一、随机抽样 1.1 将随机抽样应用于扑克牌 1.2 种子值 ​1.3 模拟骰子 1.4 比重的设置 二、再谈向量数据的抽取——以islands为实例 三、数据框数据的抽取——重复值的处理 ​3.1 重复值的搜索 3.2 which()函数 3.3 抽取数据是去除重复值 四、数据框数据的抽取…

Linux命令·scp

scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的。可能会稍微影响一下速度。当你服务器硬盘变为只读 read only system时&#xff0c…

【深度学习】第一门课 神经网络和深度学习 Week 2 神经网络基础

2.1 二元分类 前言 第二周的主题是学习神经网络的基础知识。 实现神经网络需要用到一些重要的技术和技巧,比如怎样处理包含大量样本的训练集。 在神经网络的计算中,还会有前向暂停、前向传播、反向暂停和反向传播等步骤,本周会对它们进行…

面试一个6年经验测试员:一年经验硬生生用了六年....

在众多面试中,对于那个工作了6年的面试者,我印象很深刻,因为最开始拿到简历的时候,我一摸:"这简历,好厚啊!"再一看,工作6年。 于是我去找了我的领导,我说:“这人我应该没…

C++入门基础知识总结(超详细)

目录 C入门基础知识之什么是C? C入门基础知识看看C的历史版本: C入门基础知识关键字 C入门基础之C的命名空间 C入门基础命名空间的使用 C入门基础知识的输入和输出 C入门基础知识-缺省参数 C入门基础-C函数重载 extern “C” C入门基础知识-引用 C入门基…

图像处理:图像增广算法

目录 前言 图像增广算法 a.图像旋转 b.图像亮度调整 c.图像裁剪及拼接 实验分析 本章小结 前言 图像增广算法在计算机视觉领域扮演着至关重要的角色。随着深度学习的兴起,大规模数据集的需求变得更加迫切,而图像增广算法可以通过对原始图像进行一…

手把手教你安装PaddleDetection(最新CUDA11.7版本)

前言 本文记录一下在linux系安装PaddleDetection的过程,使用Conda的方式来安装; (尝试过docker的方式,无法获取镜像;尝试过pip的方式,提升找不到库;最终使用Conda成功安装了。) 目…

什么是中国版软件能力成熟度之CSMM

当前,中国软件产业蓬勃发展,产业增速迅猛,发展韧性和潜力进一步凸显。由于我国长期缺乏相关的自主标准,20多年来国外标准在我国软件评估领域占据主导地位,不仅阻碍了我国自主产业发展,甚至通过评估等手段可…

【STM32CubeMX项目】小时钟V1.0

前言 基于STM32CubeMxSTM32F103C6T6编写时钟功能。现在以及能实现时钟的简单功能,做文记录下。还有很多可以改进的地方,也算留下的基础版本下来备份吧。我愿称之为V1.0版本。可供学习参考。 实物 引脚接线: OLED STM32F103 SCL --> PB8 SD…

使用JS手动实现SementicUI的分页,解决页数过多的问题.

自己使用SemanticUI官网的分页组件, 但是有很多细节问题并没有解决方案,如果只是需要而分页,将页数渲染在分页组件上的话,那倒很简单,但是页面有很多的话,假如100页,那么整个tbody会随着tfoot…