c++动态内存管理/模板

一,动态内存管理

(1)C语言和c++区别

在C语言中,我们常用malloc和calloc申请空间,用free来释放空间,而现在我们更多的情况下用new来申请空间,用delete来释放空间。

申请一个空间:

int* p2 = (int*)malloc(sizeof(int));//空间值为随机值
int* p3 = new int;//空间值为随机值

申请多个空间:

int* p4 = (int*)malloc(sizeof(int) * 10);
int* p5 = new int[10];

释放一个空间:

free(p2);

delete p3;

释放多个空间:

free(p4);

delete[ ] p5;

(2)申请空间的同时进行初始化:

int* p6 = new int(10);申请4个字节,一个空间,用()进行初始化
int* p7 = new int[10] {1, 2};申请多个空间,[ ]里面写申请空间的个数,{ }中,写初始化的值
int* p8 = new int[10] {};//默认为0,当写成这个样子的时候,默认是初始化为零,如果没有写{}则初始化为随机值(不同的编译器也有可能不同)

为什么出++中改用new来申请空间,而不用malloc?

答:因为malloc没有办法很好的支持动态申请的自定义对象初始化。

例如,用new来开辟自定义类型的空间并初始化

class A {
private:  int _a;
public:
    A(int a = 0)
        :_a(a)
    {}
}

A* P2 = new A;
A* P3 = new A(3);

delete P2;
delete P3;

A* P4 = new A[10];
delete[ ] P4;

将A类实例化为aa1,aa2,并开辟一块空间,将这两个对象放到里面:

A aa1(1);
A aa2(4);
A* P5 = new A[10]{ aa1,aa2 };
delete[] P5;

以上式子可以简写为以下代码:

A* P6 = new A[10]{ A(1),A(5) };
delete[] P6;

继续将其简化(运用:隐式类型转换):

A* P7 = new A[10]{ 1,5 };
delete[] P7;

——————————————————————————————

(3)new和delete

用stack类,来深入探究一下new和delete的用法:

class Stack {
private:
    int* _arr;
    int _top;
    int _capacity;
public:
    Stack(int capacity=4) {
        int* _arr = new int[capacity];
        _top = 0;
        _capacity = capacity;
    }
    ~Stack() {
        delete _arr;

    }
    void push(int val) {
        _arr[_top] = val;
        _top++;
    }
};

实例化一个对象,并将对象初始化为n

int n; cin >> n;
Stack* pst = new Stack(n);

由此可知:这里在栈上开辟了对象的空间,并调用了构造函数(开辟了数组的空间,也就是在堆上开辟了空间)

delete pst;

由此可知:调用了析构函数,释放了堆上的空间(数组的空间),并释放了栈上对象的空间

(4)operator new和operator delete

operator new的用法:

operator new的用法与malloc的用法相似,这时这里开辟空间失败时,不会返回null,而是直接抛异常
例如:Stack* pst = (Stack*)operator new (sizeof(Stack));

在执行这条代码时:int* arr = new int[10];会调用operator new[ ],它又会调用operator new。

注意:当申请一块空间时,用的是new ,与之相对的是delete,但对于多块空间来说,用的是new[ ],而与之相对的是delete [ ],在使用时要匹配的使用,不同的编译器对这两种方式有不同的处理方式,如果随意匹对使用,会在意想不到的地方冒出bug。

总结:要匹配使用

(5)new和operator new ,delete和operator delete联系

new和operator new 区别:new里面包含了operator new和构造函数

delete和operator delete:delete里面包含了operator delete和析构函数

一般来说:我们通常使用new和delete,operator new和operator delete一般是由编译器来使用的(我们使用new时,编译器再调用operator new)但是如果我们就是想用operator new(也就是说:想将开辟空间和实例化分开来进行)也可以由以下代码实现:

开辟空间:Stack* pst1 = (Stack*)operator new (sizeof(Stack));
调用构造函数:new(pst1)Stack(4);(这里用到了:显示调用构造函数)

注意:不可以写成pst1->Stack(4);来调用构造函数。但可以pst1->~Stack()来调用析构,operator delete(pst1);

pst1->~Stack();
operator delete(pst1);//这两步相当于直接调用delete

(6)总结:malloc和new,free和delete区别

1,malloc和free是函数,new和delete是操作符
2,malloc申请的空间不会初始化,new可以初始化
3,malloc需要手动计算空间的大小,new不需要
4,malloc申请失败会返回null,new抛异常
5,malloc的返回值是void*,所以必须要强转
6,new会调用构造函数,delete会调用析构函数 

二,内存区间

·1,代码区(常量区):存放程序代码;

·2,全局变量与静态变量区(数据段):存放全局变量和静态变量以及对象;

·3,栈区(局部变量区):存放局部变量;

·4,堆区(自由存储区):存放动态分配对象。

动态:分配内存(运行时) 存储(堆区) 释放内存(手动释放)

静态:分配内存(编译时) 存储(栈区) 释放内存(自动释放)

小试牛刀:

int gg = 1;
static int ss = 1;
void test() {
    static int aa = 1;
    int bb = 1;
    int num[10] = { 1,2,3,4 };
    char char2[] = "abcd";
    const char* pchar3 = "abcd";
    int* p1 = (int*)malloc(sizeof(int) * 4);
    free(p1);
}

————————————————————————————

gg 为全局变量,储存在静态区
ss 静态变量,在静态区
void test() {
    aa静态变量,在静态区
    bb为局部变量,储存在栈
    num为局部变量,储存在栈
    char2为局部变量,储存在栈(将常量区的abcd\0,拷贝到char2数组中)
    *char2;//栈(数组名代表首元素地址,解引用,指向首元素)
    const char* pchar3 = "abcd";//栈(变量为指针,存放地址,这个地址指向常量区的字符串)这个地址存放在栈上
    *pchar3;//常量区
     p1 //栈(指针)
    *p1;//堆(在堆上开辟空间)
}

如果堆上的空间不手动进行释放,会引起内存泄漏,内存泄漏在长期运行的程序上危害极大

三,模板:

分为函数模版和类模板,模版的参数是一个泛型,也就是不同类型的参数可以调用同一个模版来实现功能,极大的简化了代码,和人工成本。编译器通过参数的不同,用模板实例化生成对应的函数或者类。

写法:template<typename/class T>放在函数或者类的前面

模板的参数可以有多个,例如:template<typename T1, typename T2>

函数模板:

template<typename T>
void Swap(T& a,T& b) {
    T tmp = a;
    a = b;
    b = tmp;
}

类模板:

template<class T>
class Stack2 {
private:
    T* _arr;
    int _top;
    int _capacity;
public:
    Stack2(int capacity = 4) {
         _arr = new T[capacity];
        _top = 0;
        _capacity = capacity;
    }
    ~Stack2();
    void push(const T& val) {
        _arr[_top] = val;
        _top++;
    }
};

实例化的时候写法为,类型+引用,这里的类型不是类名,是类名<T>:

Stack2<int > s1;
Stack2<double > s1;

当模板只有一个参数,但参数确实不同的类型时,可以进行一下方法进行处理:

template<typename T >
T Add(const T& a, const T& b) {
    return a + b;
}

cout << Add((int)2.8, 3) << endl;
cout << Add(2.8, (double )3) << endl;
cout << Add<int >(2.8, 3) << endl;
cout << Add<double >(2.8, 3) << endl;

多参数的模板:

template<class T,int n>
class Num {
private:
    T arr[n];
public:
    Num(T s[]) {
        for (size_t i = 0; i < n; i++)
        {
            arr[i] = s[i];
        }
    }
};
    int arr[7] = { 1,2,3,4,5,6,7 };
    Num<int,7> num1(arr);//这样进行初始化
    

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

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

相关文章

微服务项目收获和总结---第5天(定时发布)

延迟任务 目录 延迟任务技术对比&#xff1a; Redis实现定时任务&#xff1a;​编辑新增任务&#xff1a;取消任务&#xff1a;拉取任务&#xff1a;Zset定时刷新数据到List中&#xff1a;分布式锁实现定时任务只刷新一次&#xff1a; 技术对比&#xff1a; Redis实现定时任…

香橙派 AIpro 昇腾 Ascend C++ 分类模型适配

香橙派 AIpro 昇腾 Ascend C 分类模型适配 flyfish 文章目录 香橙派 AIpro 昇腾 Ascend C 分类模型适配前言一、PyTorch官网resnet模型处理方式1、PyTorch模型 导出 onnx格式2、完整测试 输出top1结果3、完整测试 输出top5结果 二、YOLOv8官网resnet模型Python处理方式三、昇腾…

web学习笔记(五十九)

目录 1.style样式 1.1作用域 scoped 1.2 less和 sass 1.3 less和 sass两者的区别 2. 计算属性computed 3. 响应式基础reactive() 4. 什么是MVVM? 1.style样式 1.1作用域 scoped scoped表示样式作用域&#xff0c;把内部的样式仅限于当前组件模板生效&#xff0c;其…

云衔科技:为什么推荐使用zoho crm客户管理系统?

在当今快速变化的商业环境中&#xff0c;企业对高效、智能化的客户关系管理&#xff08;CRM&#xff09;系统的需求日益增长。Zoho CRM&#xff0c;作为全球领先的企业级CRM解决方案提供商&#xff0c;凭借其全面的功能、高度的可定制性、以及无缝集成的生态系统&#xff0c;成…

mybatis plus leftjoin 表如何去掉自动添加deleted=0条件

Mybatis Plus 在进行多表查询时&#xff0c;默认会添加逻辑删除的过滤条件&#xff0c;例如 deleted0&#xff0c;这是为了在查询时自动过滤掉被逻辑删除的数据。如果你希望在某个 LEFT JOIN 查询中去掉这个自动添加的条件&#xff0c;可以通过以下方式实现&#xff1a; 全局配…

探寻导师:2024年最新研究生导师评价汇总

随着考研热潮的不断升温&#xff0c;对于研究生导师的选择变得愈发重要。导师不仅关系到研究生的学术成长&#xff0c;还直接影响到未来的职业发展。然而&#xff0c;如何找到一位合适的导师成为许多考生头疼的问题。为了帮助广大考生更好地选择导师&#xff0c;整理了最新最全…

Nature 正刊!瑞典于默奥大学研究团队在研究全球河流和溪流的甲烷排放中取得新进展

甲烷(CH4)是一种强有力的温室气体&#xff0c;自工业革命以来&#xff0c;其在大气中的浓度增加了两倍。有证据表明&#xff0c;全球变暖增加了淡水生态系统的 CH4 排放&#xff0c;为全球气候提供了积极的反馈。然而&#xff0c;对于河流和溪流来说&#xff0c;甲烷排放的控制…

区间类贪心,蓝桥云课 打折

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 0打折 - 蓝桥云课 (lanqiao.cn) 二、解题报告 1、思路分析 思路很简单&am…

spark3.5.1 thriftserver paimon0.9 Datagrip

目的 启动spark thriftserver(支持paimon) 并使用Datagrip 使用 $SPARK_HOME/sbin/start-thriftserver.sh \--conf spark.sql.catalog.paimonorg.apache.paimon.spark.SparkCatalog \--conf spark.sql.catalog.paimon.warehousefile:/Users/thomas990p/data/paimon \--conf …

c++(五)

c&#xff08;五&#xff09; 继承基类和派生类继承的格式继承的方式三种:public、private、protected 继承的规则多层继承多重继承 类与类的关系 继承 一个新类从已有的类那里获得其已有特性(属性、行为)&#xff0c;这种现象称为类的继承 基类和派生类 <1>从已有的类…

WPS PPT学习笔记 2 结构页的制作

制作PPT结构页 制作封面页、目录页、封底页。它们都属于结构页。而时间轴页&#xff0c;流程图页&#xff0c;框架图页这些属于内容页。 做一份PPT 讲一个故事 封面页 开头&#xff0c; 目录页 脉络&#xff0c; 各式内容页 详情&#xff0c; 封底页 结尾。 所有的结构页…

关于Windows中桌面窗口管理器的知识,看这篇文章就可以了

序言 你打开了任务管理器,发现了一个叫做“桌面窗口管理器”的东西,它是恶意软件吗?它应该在任务管理器吗?如果它应该在那里,它的作用什么?以下是你需要了解的所有信息。 什么是桌面窗口管理器 Desktop Window Manager(dwm.exe)是一个合成窗口管理器,可以在Windows…

Kotlin基础之面向对象编程

1. 类与对象 介绍 类&#xff1a;类是对象的蓝图或模板&#xff0c;它定义了对象的属性和方法。对象&#xff1a;对象是类的实例&#xff0c;具有类的属性和方法。 使用 // 定义一个类 class Person { var name: String "" var age: Int 0 // 方法 fun introdu…

打印机里失败的任务删不掉的解决办法 斑马打印机更新电脑驱动和升级打印机固件 提示ribbon out 并黄状态亮+黄供应闪

强删打印任务 WinR services.msc 停止服务 Print spooler C:\Windows\System32\spool\PRINTERS 清空文件夹下所有文件 详细 要删除打印机里失败的任务&#xff0c;可以按照以下步骤操作&#xff1a; 停止打印服务&#xff1a;您需要停止Windows系统中的“Print Spooler”服…

VScode代码片段自动转图标

注&#xff1a;在VScode编辑器中&#xff0c;编辑html、vue等文件时&#xff0c;特定代码片段&#xff08;token/xxx’等&#xff09;自动转图标显示&#xff0c;按住“ctrl鼠标左键”还可跳转“https://icones.js.org/collections”&#xff0c;个人感觉干扰代码编写&#xff…

手把手教你写Java项目(1)——流程

个人练手项目的一般流程&#xff1a; 个人练手项目的流程通常相对简单和灵活&#xff0c;但仍然遵循一定的步骤来确保项目的顺利进行。流程相对较为详细&#xff0c;不是所有流程都要实现&#xff0c;一些仅供参考。主要是让大家对项目有初步的了解&#xff0c;不至于无法入手…

Android Compose 七:常用组件 Image

1 基本使用 Image(painter painterResource(id R.drawable.ic_wang_lufei), contentDescription "" ) // 图片Spacer(modifier Modifier.height(20.dp))Image(imageVector ImageVector.vectorResource(id R.drawable.ic_android_black_24dp), contentDescript…

Round-Robin 调度逻辑算法

Round-Robin 调度逻辑算法 1 Intro1.1 固定优先级1.2 Round-Robin算法 之前上学还是工作&#xff0c;都接触过调度算法&#xff1a;Round-Robin和weight-Round Robin算法&#xff0c;但只知道它的功能和目的是什么&#xff0c;没有具体了解如何实现的&#xff1b; 现在是工作上…

微信生态系统介绍

微信生态系统介绍 微信生态系统中&#xff0c;包含多种不同的工具和功能来满足用户和企业的不同需求。以下是关于微信小程序、公众号、订阅号、服务号、订阅通知和服务通知之间的关系及区别的详细介绍&#xff1a; 微信小程序 微信小程序是一种无需下载安装即可使用的应用&a…

maven聚合工程整合springboot+mybatisplus遇到的问题

前言&#xff08;可以直接跳过看下面解决方法&#xff09; 项目结构 两个module&#xff1a; yema-terminal-boot 是springboot项目&#xff0c;子包有&#xff1a;controller、service、dao 等等。属于经典三层架构。那么&#xff0c;该module可以理解为是一个单体项目&…