当前位置: 首页 > news >正文

C++ 动态内存分配

在C++中动态内存的分配技术可以保证程序在允许过程中按照实际需要申请适量的内存,使用结束后还可以释放,这种在程序运行过程中申请和释放的存储单元也称为堆。 申请和释放过程一般称为建立和删除。

在C++程序中,建立和删除堆对象使用两个运算符:new和delete。

1.运算符new的功能是动态分配内存,或者称为动态创建堆对象,语法形式为:

new 数据类型(初始化列表参数);

该语句在程序运行过程中申请分配用于存放指定类型数据的内存空间,并根据初始化参数列表中给出的值进行初始化。如果内存申请成功,new运算符便返回一个指向新分配内存首地址的类型的指针,可以通过这个指针对该内存空间进行访;如果申请失败,会抛出异常。

(1)对于基本类型的对象

如果建立的对象是一个基本类型的变量,初始化过程就是赋值,例如:

int *p;
p=new int(2);

动态分配了用于存放int型数据的内存空间,并将初值2存入该空间中,然后将首地址赋给指针p。

【注意】对于基本数据类型,如果不希望在内存分配后设定初值,可以把括号省去,例如:

int *p=new int;

如果保留括号,但括号中不写任何数值,则表示用0对该对象初始化,例如:

int *p=new int();

(2)对于类类型的对象
要根据初始化参数列表的参数类型和个数调用该类的构造函数。

在用new建立一个对象时,如果该类存在用户自定义的默认构造函数,则“new T”和“new T()”这两种写法的效果时相同的,都会调用这个默认的构造函数。但若用户没有定义默认的构造函数,使用“new T”创建对象时,会调用系统生成的隐含的默认构造函数;使用“new T()”创建对象时,系统除了执行默认构造函数会执行的操作外,还会为基本数据类型和指针类型的成员用0赋初值,而且这一过程是递归的。也就是说,如果该对象的某个成员对象也没有用户自定义的默认构造函数,那么对该成员的基本数据类型和指针类型的成员,同样会被以0赋初值。

2.运算符delete是用来删除由new建立的对象,释放指针所指向的内存空间。

格式为:

delete 指针名;

如果删除的是对象,该对象的析构函数将被调用。对于new建立的对象,只能用delete进行一次删除操作,如果同一内存空间多次使用delete进行删除将会导致运行错误。

【注意】用new分配的内存,必须用delete加以释放,否则会导致动态内存分配的内存无法回收,使得程序占据的内存越来越大,这叫做“内存泄漏”。

【例】动态创建对象

class Point
{
public:Point() :x(0), y(0){cout << "调用默认构造函数" << endl;}Point(int x, int y) :x(x), y(y){cout << "调用构造函数" << endl;}~Point(){cout << "调用析构函数" << endl;}int getX() { return x; }int getY() { return y; }void move(int newX, int newY){x = newX;y = newY;}
private:int x, y;
};int main()
{cout << "创建第一个对象:" << endl;Point* p1 = new Point;//动态创建对象,没有给出参数列表,因此调用默认的构造函数delete p1;//删除对象,自动调用析构函数cout << "创建第一个对象:" << endl;Point* p2 = new Point(1,2);//动态创建对象,并给出参数列表,因此调用有参数的构造函数delete p2;//删除对象,自动调用析构函数return 0;
}

运行结果:
在这里插入图片描述
3.使用运算符new也可以创建数组对象,这时需要给出数组的结构说明。用new运算符动态创建一维数组的语法形式为:

new 类型名[数组长度]

其中数组长度指出了数组元素的个数,它可以是任何能够得到正整数值得表达式。

用new动态创建一维数组时,在方括号后面仍然可以加小括号“()”,但小括号内不能带参数。是否加“()”得区别在于,不加“()”,则对数组每个元素得初始化,与执行“new T”时所进行得初始化方式相同;加“()”,则与执行“new T”所进行初始化得方式相同。例如,如果这样动态生成一个整型数组:

int *p=new int[10]();

则可以方便地为动态创建的数组用()初始化。

如果是用new建立得数组,用delete删除时在指针名前面要加“[]”,格式如下:

delete []指针名;

【例】动态创建对象数组

class Point
{
public:Point() :x(0), y(0){cout << "调用默认构造函数" << endl;}Point(int x, int y) :x(x), y(y){cout << "调用构造函数" << endl;}~Point(){cout << "调用析构函数" << endl;}int getX() { return x; }int getY() { return y; }void move(int newX, int newY){x = newX;y = newY;cout <<"(" <<x <<"," << y<<")" << endl;}
private:int x, y;
};int main()
{Point* p = new Point[2];p[0].move(5, 10);p[1].move(15, 20);cout << "删除对象:" << endl;delete[]p;return 0;
}

运行结果:
在这里插入图片描述
这是利用动态内存分配操作实现了数组得动态创建,使得数组元素得个数可以根据运行时得需要而确定。但是建立和删除数组得过程使得程序略显繁琐,更好得方法是将数组得建立和删除封装起来,形成一个动态数组类。

另外,在动态数组类中,通过类得成员函数访问数组元素,可以每次在访问之间检查一下下标是否越界,使得数组下标越界得错误能够及早发现。这种检查,可以通过C++的assert来进行。assert的含义是“断言”,它是标准C++的cassert头文件中定义的一个宏,用来判断一个条件表达式的值是否为true,如果不为true,则程序会中止,并且报错,这样就很容易将错误定位。一个程序一般可以以两种模式编译——调试(debug)模式和发行(release)模式,assert只在调试模式下生效,而在发行模式下不执行任何操作,这样兼顾了调试模式的调试需求和发行模式的效率需求。

【注意】由于assert只在调试模式下生效,一般用assert只是检查程序本身的逻辑错误,而用户的不当输入造成的错误,则应当用其他方式加以处理。

【例】动态数组类

class Point
{
public:Point() :x(0), y(0){cout << "调用默认构造函数" << endl;}Point(int x, int y) :x(x), y(y){cout << "调用构造函数" << endl;}~Point(){cout << "调用析构函数" << endl;}int getX() { return x; }int getY() { return y; }void move(int newX, int newY){x = newX;y = newY;cout << "(" << x << "," << y << ")" << endl;}
private:int x, y;
};
//动态数组类
class Arr
{
public:Arr(int size) :size(size){points = new Point[size];}~Arr(){cout << "删除对象:" << endl;delete[]points;}//获得下标为index的数组元素Point& element(int index){assert(index >= 0 && index < size);//如果数组下标越界,程序中止return points[index];}
private:Point* points;//指向动态数组的首地址int size;//数组大小
};int main()
{int count;cout << "请输入要创建的对象的个数:";cin >> count;Arr points(count);//创建对象数组points.element(0).move(5,0);//访问数组元素的成员points.element(1).move(15,20);return 0;
}

运行结果:
在这里插入图片描述
在main函数中,只是建立一个Arr类的对象,对象的初始化参数size指定了数组元素的个数,创建和删除对象数组的过程都由Arr类的构造函数和析构函数完成。

相关文章:

C++ 动态内存分配

在C中动态内存的分配技术可以保证程序在允许过程中按照实际需要申请适量的内存&#xff0c;使用结束后还可以释放&#xff0c;这种在程序运行过程中申请和释放的存储单元也称为堆。 申请和释放过程一般称为建立和删除。 在C程序中&#xff0c;建立和删除堆对象使用两个运算符&…...

设计模式——面向对象的7大设计原则

1.单一职责原则 一个类中最好只放一种类型的方法&#xff0c;比如Dao中只有和数据库交互相关的代码。实现高内聚&#xff0c;低耦合。 2.开闭原则 对外拓展开放&#xff0c;对内修改关闭&#xff0c;有新的需求时不要修改已有代码&#xff0c;而是添加新的代码&#xff0c;比…...

智慧防汛,数字科技的力量

随着夏日的脚步临近&#xff0c;台风季节即将降临。对于那些居住在沿海地区的人们来说&#xff0c;台风是一种常见的自然灾害&#xff0c;其带来的风雨可能对生命和财产造成严重威胁。然而&#xff0c;随着数字科技的飞速发展&#xff0c;可视化技术为防汛抗台工作带来了全新的…...

“中国软件杯”飞桨赛道晋级决赛现场名单公布

“中国软件杯”大学生软件设计大赛是由国家工业和信息化部、教育部、江苏省人民政府共同主办&#xff0c;是全国软件行业规格最高、最具影响力的国家级一类赛事&#xff0c;为《全国普通高校竞赛排行榜》榜单内赛事。今年&#xff0c;组委会联合百度飞桨共同设立了“智能系统设…...

JDBC处理批量数据提高效率

文章目录 0 说明1 如何使用jdbc操作数据库1.1 加载数据库驱动1.2 建立数据库连接1.3 创建Statement或者PreparedStatement用来执行SQL1.4 开始执行SQL语句1.5 处理结果集1.6 关闭连接1.7 完整代码 2 批量操作数据库3 如何打印SQL语句4 jdbc常用开源类库 1 JDBC实现往MySQL插入百…...

使用css和js给按钮添加微交互的几种方式

使用css和js给按钮添加微交互的几种方式 在现实世界中&#xff0c;当我们轻弹或按下某些东西时&#xff0c;它们会发出咔嗒声&#xff0c;例如电灯开关。有些东西会亮起或发出蜂鸣声&#xff0c;这些响应都是“微交互”&#xff0c;让我们知道我们何时成功完成了某件事。在本文…...

react面试之context的value变化时,内部所有子组件是否变化

上测试代码 // context const state {a: 1,b: 1, } const context createContext(state);export default context; // A组件 const A () > {const { a } useContext(context);return (<div>{a}</div>) } export default A;// B组件 const B () > {cons…...

使用okHttp不走代理问题

背景 某日使用okhttp设置代理并发送爬虫请求时&#xff0c;发现部分url请求没有走代理直接和目标url建立了连接&#xff0c;伪代码如下。初始化okhttpClient时设置了proxySelecter代理&#xff0c;但是调用okhttpClient.newCall请求时并没用调用proxySelecter.select函数获取代…...

python moviepy 自动化音视频处理实践

MoviePy是一个用于视频编辑的Python库。它提供了一种简单且直观的方式来处理视频文件&#xff0c;包括剪辑、合并、裁剪、添加文本、添加音频等操作。使用MoviePy&#xff0c;你可以通过编写Python代码来创建和编辑视频&#xff0c;而无需使用复杂的视频编辑软件。 MoviePy建立…...

聊聊混合动力汽车和纯电骑车的优势和劣势

混合动力汽车和纯电动骑车是两种不同的交通工具&#xff0c;它们都有各自的优势和劣势。本文将分别探讨混合动力汽车和纯电动骑车的优势和劣势&#xff0c;并为文章提供三个备选的好听的标题。 混合动力汽车是一种结合了内燃机和电动机的汽车&#xff0c;它可以同时利用燃油和电…...

算法训练Day39|62.不同路径 ● 63. 不同路径 II

LeetCode:62.不同路径 62. 不同路径 - 力扣&#xff08;LeetCode&#xff09; 1.思路 想象成矩阵填格子&#xff0c;两个关键点&#xff0c;初始化和递推公式。 初始化除点&#xff08;0&#xff0c;0&#xff09;第一行第一列均为1&#xff0c;递推公式推导dp[i][j] dp[i …...

react中hooks分享

一. HOOKS是什么 在计算机程序设计中&#xff0c;钩子一词涵盖了一系列技术&#xff0c;这些技术用来通过拦截函数调用、消息或在软件组件之间传递的事件来改变或增加操作系统、应用程序或其他软件组件的行为。处理这些被截获的函数调用、事件或消息的代码称为“hook”。 在r…...

LeetCode1207. 独一无二的出现次数

题干 给你一个整数数组 arr&#xff0c;请你帮忙统计数组中每个数的出现次数。 如果每个数的出现次数都是独一无二的&#xff0c;就返回 true&#xff1b;否则返回 false。 示例1&#xff1a; 输入&#xff1a;arr [1,2,2,1,1,3] 输出&#xff1a;true 解释&#xff1a;在该…...

【maven】构建项目前clean和不clean的区别

其实很简单&#xff0c;但是百度搜了一下&#xff0c;还是没人能简单说明白。 搬用之前做C项目时总结结论&#xff1a; 所以自己在IDE里一遍遍测试程序能否跑通的时候&#xff0c;不需要clean&#xff0c;因为反正还要改嘛。 但是这个项目测试好了&#xff0c;你要打成jar包给…...

Stable Diffusion 硬核生存指南:WebUI 中的 CodeFormer

本篇文章聊聊 Stable Diffusion WebUI 中的核心组件&#xff0c;强壮的人脸图像面部画面修复模型 CodeFormer 相关的事情。 写在前面 在 Stable Diffusion WebUI 项目中&#xff0c;源码 modules 目录中&#xff0c;有一个有趣的目录叫做 CodeFormer&#xff0c;它就是本文的…...

从零开始理解Linux中断架构(24)软中断核心函数__do_softirq

1)概要 __do_softirq函数处理是总是尽可能的执行所有未决软中断。 (1)关闭软中断:在preempt_count设置软中断标志:SOFTIRQ_OFFSET 让in_interrupt检查条件为真,进入软中断处理临界区,后面进来的处理请求,需要检查in_interrupt(),从而达到禁止本cpu上的软中断嵌套的目…...

【云原生】Kubernetes中deployment是什么?

目录 Deployments 更新 Deployment 回滚 Deployment 缩放 Deployment Deployment 状态 清理策略 金丝雀部署 编写 Deployment 规约 Deployments 一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。 你负责描述 Deployment 中的 目标状态&#xff0c;而 De…...

sk_buff操作函数学习

一. 前言 内核提供了大量实用的操作sk_buff的函数&#xff0c;在开发网络设备驱动程序和修改网络协议栈代码时需要用到。这些函数从功能上可以分为三类&#xff1a;创建&#xff0c;释放和复制socket buffer&#xff1b;操作sk_buff结构中的参数和指针&#xff1b;管理socket b…...

conda create时候出现JSONDecoderError解决方法

起因是我的conda出现了JSONDecoderError&#xff0c;这个我搜了一下是因为某些配置文件错误&#xff0c;所以让我update conda&#xff0c;于是我先用了下面的指令&#xff1a; conda update conda 但是在执行过程中依然会出现 JSONDecoderError的问题&#xff0c;后来参考了这…...

Electron 工具进程utilityProcess 使用中遇到的坑点汇集

简介 这是基于 node.js 中的子进程的概念推出来的&#xff0c;可参考链接&#xff1a;utilityProcess | Electron 官网有一句话非常重要&#xff0c;它提供一个相当于 Node.js 的 child_process.fork API&#xff0c;但使用 Chromium 的 Services API 代替来执行子进程。这句话…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...