第八十五天学习记录:C++核心:内存分区模型
内存分区模型
C++程序在执行时,将内存大方向划分为4个区域
1、代码区:存放函数体的二进制代码,由操作系统进行管理
2、全局区:存放全局变量和静态变量以及常量
3、栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
4、堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
内存四区的意义:
不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程
1、程序运行前
在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域
代码区:
存放CPU执行的机器指令
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可
代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令
全局区:
全局变量和静态变量存放在此
全局区还包含了常量区,字符串常量和其他常量也存放在此
该区域的数据在程序结束后由操作系统释放
#include <iostream>
using namespace std;//全局变量
int g_a = 10;
int g_b = 10;int main()
{//创建普通局部变量int a = 10;int b = 10;cout << "局部变量a的地址为:" << &a << endl;cout << "局部变量b的地址为:" << &b << endl;cout << "全局变量a的地址为:" << &g_a << endl;cout << "全局变量b的地址为:" << &g_b << endl;return 0;
}

#include <iostream>
using namespace std;//全局变量
int g_a = 10;
int g_b = 10;//const修饰的全局变量,全局常量
const int c_g_a = 10;
const int c_g_b = 10;int main()
{//全局区//全局变量、静态变量、常量//创建普通局部变量int a = 10;int b = 10;cout << "局部变量a的地址为:" << &a << endl;cout << "局部变量b的地址为:" << &b << endl;cout << "全局变量a的地址为:" << &g_a << endl;cout << "全局变量b的地址为:" << &g_b << endl;//静态变量 在静态变量前面加static,属于静态变量static int s_a = 10;static int s_b = 10;cout << "静态变量a的地址为:" << &s_a << endl;cout << "静态变量b的地址为:" << &s_b << endl;//常量//字符串常量cout << "字符串常量的地址为:" << &"hello world" << endl;//const修饰的变量//const修饰的全局变量,const修饰的局部变量cout << "全局常量a的地址为:" << &c_g_a << endl;cout << "全局常量a的地址为:" << &c_g_b << endl;const int c_l_a = 10;const int c_l_b = 10;cout << "局部常量a的地址为:" << &c_l_a << endl;cout << "局部常量a的地址为:" << &c_l_b << endl;return 0;
}

2、程序运行后
栈区:
由编译器自动分配释放,存放函数的参数值,局部变量等
注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放。
反面案例:
#include <iostream>
using namespace std;int * func()
{int a = 10;return &a;
}int main()
{int* p = func();cout << *p << endl;//第一次可以打印正确的数字是因为编译器做了保留cout << *p << endl;//第二次这个数据就不再保留的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;delete p;p = nullptr;return 0;
}
3、new操作符
c++中利用new操作符在堆区开辟数据
堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符delete
问:C语言中free指针后,指针地址不会变,c++中delete指针后,指针的地址也会改变?
答:在C语言中,调用函数free会释放指针指向的内存,并将内存返回给系统,但指针本身的值不会受到影响,仍然指向之前分配的内存地址。这是因为C语言中的指针只是一个整数变量,它存储的是地址(整数),而不是实际的对象。
而在C++中,delete运算符执行的操作与free函数类似,它会释放指针所指向的内存并将其返回给系统。不同的是,delete还会调用被删除对象的析构函数。此外,当使用delete删除堆上分配的内存后,指向该内存的指针将变为无效指针,指向的内存已经被释放,所以在C++中,删除指针后,指针的值会变成无定义的。不过,可以使用nullptr或0来表示空指针。
语法:new 数据类型
利用new创建的数据,会返回该数据对应的类型的指针。
#include <iostream>
using namespace std;//1、new的基本语法
int * func()
{//在堆区创建整型数据//new返回是该数据类型的指针int* p = new int(10);return p;
}void test01()
{int * p = func();cout << *p << endl;//堆区的数据由程序员管理开辟,程序员管理释放//如果想释放堆区的数据,利用关键字deletedelete p;//cout << *p << endl;//内存已经被释放,再次访问就是非法操作,会报错
}//2、在堆区利用new开辟数组
void test02()
{//创建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()
{test01();test02();return 0;
}
补充:
问:new int[10]后,delete[]为什么可以不在[]加10?
答:
在使用 new 运算符为动态分配内存时,会在堆上额外分配一些元数据来跟踪分配的内存区域的大小。在释放内存时,delete[] 运算符会使用这些元数据来确定应该回收的内存数量,因此你不需要指定数组的大小。
这意味着,如果你使用 new int[10] 分配了一个包含 10 个元素的整数数组,那么在释放数组时,你只需要使用 delete[] 运算符,而不必指定数组大小。
如果你指定了错误的大小,那么会发生未定义的行为。有时候这种错误可能不会导致问题,但有时候会导致程序崩溃或数据损坏。如果你不确定应该使用哪个运算符,最好查阅相关文档或咨询更有经验的开发人员。
问:malloc,free和new,delete的区别。
malloc 和 free 是在 C 语言中使用的动态内存分配和释放函数,new 和 delete 是在 C++ 语言中使用的动态内存分配和释放运算符。它们之间的主要区别如下:
-
malloc和free是函数,而new和delete是运算符。这意味着new和delete可以像其他运算符一样重载,而malloc和free不能。 -
new和delete是 C++ 的内存管理方式,它们可以用于动态分配对象,而malloc和free只是简单地分配和释放内存,不能够调用对象的构造函数和析构函数。 -
new和delete是类型安全的,它们知道要分配的内存大小,而malloc和free可以分配任意大小的内存块。 -
new和delete可以跟踪对象的数量和大小,也可以自动调用构造函数和析构函数,而malloc和free不能跟踪对象的数量和大小,也不能自动调用构造函数和析构函数。
总之,new 和 delete 操作符是建议在 C++ 中使用的内存分配和释放方式,它们更加高效、类型安全,并且能够跟踪对象的数量和大小。而 malloc 和 free 虽然可以在 C++ 中使用,但还是更多的使用在 C 语言和一些使用标准库的编程语言中。
相关文章:
第八十五天学习记录:C++核心:内存分区模型
内存分区模型 C程序在执行时,将内存大方向划分为4个区域 1、代码区:存放函数体的二进制代码,由操作系统进行管理 2、全局区:存放全局变量和静态变量以及常量 3、栈区:由编译器自动分配释放,存放函数的参数…...
Chrome远程调试webview
网址 谷歌远程调试解决方案 https://blog.csdn.net/m0_56516186/article/details/131260563Chrome远程调试webview https://blog.csdn.net/weixin_44801980/article/details/117755550...
爬虫与反爬虫的攻防对抗
一、爬虫的简介 1 概念 爬虫最早源于搜索引擎,它是一种按照一定的规则,自动从互联网上抓取信息的程序,又被称为爬虫,网络机器人等。按爬虫功能可以分为网络爬虫和接口爬虫,按授权情况可以分为合法爬虫和恶意爬虫。恶…...
【机器学习】特征工程 - 字典特征提取
「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 字典特征提取 一、特征提取API一、提取数字特征二、特征名字三、返回原始数据特征工…...
用户交互----进入游戏
一、增加交互----点击和拖动 1、点击鼠标画点的程序 设置 import pygame # Setup pygame.init() screen pygame.display.set_mode([800,600]) pygame.display.set_caption("单击画圆点") keep_going True RED (255,0,0) …...
排序算法 - 快速排序(4种方法实现)
快速排序 快速排序是啥?三数取中:1.挖坑法(推荐掌握)2.前后指针法(推荐掌握)3.左右指针法(霍尔版本)(容易出错)4.非递归实现 本篇文章的源代码在这࿰…...
C++入门知识点
目录 命名空间 命名空间定义 命名空间使用 法一:加命名空间名称及作用域限定符:: 法二:使用using部分展开(授权)某个命名空间中的成员 法三:使用using对整个命名空间全部展开(授权…...
开眼界了,AI绘画商业化最强玩家是“淘宝商家”
图片来源:由无界AI生成 7月,2023世界人工智能大会在上海召开,顶尖的投资人、创业者都去了。 创业者吐槽:投我啊,我很强。 投资人反问:你的商业模式是什么?护城河是什么? 创业者投资人…...
机器学习与深度学习——自定义函数进行线性回归模型
机器学习与深度学习——自定义函数进行线性回归模型 目的与要求 1、通过自定义函数进行线性回归模型对boston数据集前两个维度的数据进行模型训练并画出SSE和Epoch曲线图,画出真实值和预测值的散点图,最后进行二维和三维度可视化展示数据区域。 2、通过…...
大屏项目也不难
项目环境搭建 使用create-vue初始化项目 npm init vuelatest准备utils模块 业务背景:大屏项目属于后台项目的一个子项目,用户的token是共享的 后台项目 - token - cookie 大屏项目要以同样的方式把token获取到,然后拼接到axios的请求头中…...
c#webclient请求中经常出现的几种异常
WebClient是.NET Framework提供的用于HTTP请求的类,如果在使用WebClient时遇到异常,我们可以根据具体的异常类型进行处理。 以下是一些常见的WebClient异常及其处理方法: System.Net.WebException WebException通常是由于请求超时、网络连…...
设计模式-原型模式
目录 一、传统方式 二、原型模式 三、浅拷贝和深拷贝 克隆羊问题: 现在有一只羊tom,姓名为: tom,年龄为: 1,颜色为: 白色,请编写程序创建和tom羊属性完全相同的10只羊。 一、传统方式 public class Client {public static vo…...
sentinel介绍-分布式微服务流量控制
官网地址 https://sentinelguard.io/ 介绍 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自…...
基于Redisson的Redis结合布隆过滤器使用
一、场景 缓存穿透问题 一般情况下,先查询Redis缓存,如果Redis中没有,再查询MySQL。当某一时刻访问redis的大量key都在redis中不存在时,所有查询都要访问数据库,造成数据库压力顿时上升,这就是缓存穿透。…...
BrowserRouter刷新404解决方案
1、本地开发环境 在js脚本命令里加上 --history-api-fallback "scripts": {"serve": "webpack serve --config webpack.dev.js --history-api-fallback" }2、生产环境,可以修改 nglnx 配置: server {listen XXXX; //端口号…...
解决appium-doctor报opencv4nodejs cannot be found
一、下载cmake 在CMake官网下载:cmake-3.6.1-win64-x64.msi 二、安装cmake cmake安装过程 在安装时要选择勾选为所有用户添加CMake环境变量 三、检查cmake安装 重新管理员打开dos系统cmd命令提示符,输入cmake -version cmake -version四、安装opencv4no…...
安卓通过adb pull和adb push 手机与电脑之间传输文件
1.可以参考这篇文章 https://www.cnblogs.com/hhddcpp/p/4247923.html2.根据上面的文章,我做了如下修改 //设置/system为可读写: adb remount //复制手机中的文件到电脑中。需要在电脑中新建一个文件夹,我新建的文件夹为ce文件夹 adb pull …...
java常用的lambda表达式总结
一、概述 lambda表达式是JDK8中的一个新特性,对某些匿名内部类进行简化,是函数式编程; 二、基本格式 (参数列表)->{方法体代码} 三、Stream流 是jdk8中的新特性,将数据以流的形式进行操作 三、常用方法解析 3.1、准备工作 …...
分布式应用之zookeeper集群+消息队列Kafka
一、zookeeper集群的相关知识 1.zookeeper的概念 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能…...
GStreamer学习笔记(四)
Time management 仅当管道处于PLAYING状态时,可以刷新屏幕。如果不在PLAYING状态,什么都不做,因为大多数查询都会失败。 函数与知识点 GstClockTime 说明:所需的超时时间必须以GstClockTime的形式指定。即以纳秒(ns…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
