c++详解【new和delete】

说起new和delete,了解过c++的人应该都知道吧,它是用来分配内存和释放内存的两个操作符。与c语言中的malloc和free类似。

c语言中使用malloc/calloc/realloc/free进行动态内存分配,malloc/calloc/realloc用来在堆上分配空间,free将申请的空间释放掉。

malloc:

void FunTest()
{int *pTest = (int*)malloc(10*sizeof(int));         //开辟10个int型的空间大小if(pTest != NULL){free(pTest);pTest = NULL;}
}
calloc:

void FunTest()
{int *pTest = (int*)calloc(10,sizeof(int));    //分配10个int型的内存块,并将其初始化为0if(pTest != NULL){free(pTest);pTest = NULL;}
}
realloc:

void FunTest()
{int *pTest = (int*)malloc(10*sizeof(int));   realloc(pTest,20*sizeof(int));   //改变原有空间大小,若不能改变则会新开辟一段空间,并将原有空间的内容                                               拷贝过去,但不会对新开辟的空间进行初始化free(pTest);
}
这里要注意的一点是,为什么分配了空间之后,必须要用户手动去free掉呢,是因为malloc、calloc、realloc都是在堆上分配的,堆上分配的空间必须由用户自己来管理,如果不释放,就会造成内存泄漏。而栈上分配的空间是由编译器来管理的,具有函数作用域,出了函数作用域后系统会自动回收,不由用户管理,所以不用用户显式释放空间。

对于内存泄漏,我介绍一下我所见过的内存泄漏吧:

(1)申请内存但并未释放。

void FunTest()
{int *pTest1 = (int*)malloc(10*sizeof(int));*pTest1 = 0;
}
(2)程序逻辑错误,这里引出两个问题。

①同一块空间释放两次,导致崩溃;

②有一块空间没有释放,以为释放了,导致内存泄漏。

void FunTest()
{int *pTest1 = (int*)malloc(10*sizeof(int));int *pTest2 = (int*)malloc(10*sizeof(int));pTest1 = pTest2;free(pTest1);free(pTest2);
}
(3)程序的误操作,将堆破坏。申请的空间不足以赋值,释放导致崩溃。

void FunTest()
{char *pTest1 = (char*)malloc(5);strcpy(pTest1,"hello world");free(pTest1);
}
(4)当释放时传入的地址和分配时的地址不一样时,会导致崩溃。
void FunTest()
{int *pTest1 = (int*)malloc(10*sizeof(int));assert(pTest1 != NULL);pTest1[0] = 0;pTest1++;      //地址向后移动了一位free(pTest1);
}
上述简单的介绍了一下c语言中动态内存管理的类型,下面讲解一下c++中的动态内存管理。

c++中是通过new和delete操作符进行动态内存管理的。

先用一张图简单的说明一下new和delete的含义:


记住:new和delete就像malloc和free一样,都要成对使用哦

我们再看一个这样的表达式:

string *s = new string("a value");     //分配并初始化一个string对象
string *str = new string[10];          //分配10个默认初始化的string对象
这两个new表达式,一个是分配一个对象,一个是分配对象数组。内部实现也是截然不同。

这是string *s = new string("a value"); 这句表达式内部的实现:



我们可以看出new内部的调用顺序:(初始化一个对象时)


new内部的调用顺序:(初始化若干个对象时)


同样地,delete对象时,调用顺序为:(delete单个对象时)



delete对象时,调用顺序为:(delete多个对象时)



接下来,看一下动态内存分布图:


new和delete与malloc和free一样,都是存在堆上的。那么,二者有什么差别呢?


· 总结new/delete和malloc/free的区别和联系:

1. 它们都是动态管理内存的入口。

2. malloc/free是C/C++标准库的函数,new/delete是C++操作符。

3. malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间还会调用构造

析构函数进行初始化与清理(清理成员)。

4. malloc/free需要手动计算类型大小且返回值为void*,new/delete可自己计算类型的大小

对应类型的指针。

5.new/delete的底层调用了malloc/free。

6.malloc/free申请空间后得判空,new/delete则不需要。

7.new直接跟类型,malloc跟字节数个数。





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

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

相关文章

Stack/Queue与Vector/List的联系

Vector:(顺序表【数组存储】) 1.当申请的空间不足的时候,需要再次开辟一块更大的空间,并把值拷过去。 2.对于尾删和尾插是比较方便的,只需要改动最后一个元素即可。不会改动原有的空间。适用于多次重复的对尾部插删。 3.顺序存储&#xff…

用栈实现后缀表达式求解问题

一、问题概述: 人们经常书写的数学表达式属于中缀表达式,今天要解决的是,后缀表达式的求解问题。 如下图分别为举例的中缀表达式和后缀表达式: 二、解决思路 我们用栈存储后缀表达式中的数据部分,当遇到操作符时就取…

用栈和递归求解迷宫问题

一、问题概述 小时候,我们都玩过走迷宫的游戏吧。看一下这个图例: 遇到这种问题时,我们第一反应都会先找到迷宫的入口点,然后对上下左右四个方向进行寻迹, 检测当前位置是否是通路,是否可以通过&#xff0…

【c语言】棋盘游戏--三子棋

一、问题概述 大家都玩过棋盘游戏吧,像五子棋一样,玩家或者是电脑一人下一次,当玩家或者是电脑的某一方先将各自的五个棋子下成一条线时,谁就赢,棋盘游戏就会结束。 当然,我今天要介绍的是三子棋&#xff…

[数据结构]求解迷宫最短路径问题

一、问题概述 之前,我们了解了如何实现迷宫问题(对于迷宫只有一个出口可以通的情况),事实上我们的迷宫有多个出口,对于每条路径来说,有长有短,所以在这里,我们讨论一下迷宫的最短路…

[STL]List的实现

STL(Standard template Library):c的标准模板库 STL是算法和数据结构的软件框架,它包含了六大组件:算法、迭代器、容器、仿函数、配接器、空间配置器。 迭代器:我们可以把迭代器相当于智能指针,&#xff0…

vc++6.0的应用程序打不开肿么办

今天早起,有同学问到我关于vc6.0的安装过程中遇到的问题,我听了之后想想还是写篇博客给大家看一下吧。因为我之前也遇到过类似的问题。当时也是挺着急的。 大家遇到的问题估计就是这样吧~~(下载后打不开) 请看-->解决步骤&…

【数据结构】广义表

一、问题概述 广义表是非线性的数据结构,是由若干个元素组合而成的,广义表中可以有子表,类似这样的: 我们以C(a,b,(c,d))为例,将它定义为这样的数据结构: 我们会给定字符串的形式,如&#xff…

【数据结构】普通二叉树的实现

一、问题概述 树是n个有限个数据的集合,形如: 它像不像倒着的树呢?我们把它看成是一种数据结构----树。它的第一个节点称作树的根,最底下的那些节点称作树的叶子。 我们今天所要研究的是二叉树,即父节点最多只有两个孩…

setitimer用法说明

函数原型&#xff1a; int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value) 函数作用&#xff1a; 可用来实现延时和定时的功能 头文件&#xff1a; #include <sys/time.h> 参数详解 用一把&#xff1a;一个例子 #include &…

哈希表(闭散列、拉链法--哈希桶)

哈希表&#xff0c;也称散列表&#xff0c;是一种通过key值来直接访问在内存中的存储的数据结构。它通过一个关键值的函数&#xff08;被称为散列函数&#xff09;将所需的数据映射到表中的位置来访问数据。 关于哈希表&#xff0c;主要为以下几个方面&#xff1a; 一、哈希表…

僵尸进程的产生和SIGCHLD信号

核心句子 子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自 定义SIGCHLD信号的处理函数。 僵尸进程的产生&#xff1a; #include "head.h" #include <unistd.h> #include <signal.h>int main() {key_t key ftok(&quo…

海量数据处理--位图(BitMap)

对于海量数据这个词&#xff0c;大家不难理解吧。主要是针对给定的数据量特别大&#xff0c;占用内存特别大的情况。那么和位图有什么关系呢。看下面一个腾讯的海量数据的例子吧。 例&#xff1a;给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0…

ps命令与top命令参数意义详解

文章目录1.ps -l2.ps aux3.top面试经常被问道&#xff0c;特别是top。1.ps -l 参数解释F代表这个程序旗标 (process flags)&#xff0c;说明这个程序的总结权限&#xff0c;常见号码有&#xff1a;o 若为 4 表示此程序的权限为 root &#xff1b;o 若为 1 则表示此子程序仅进行…

哈希拓展--布隆过滤器

一、问题概述 布隆过滤器是由布隆提出来的&#xff0c;是由一个很长的二进制序列和一系列的映射函数组成。主要用于检测一个元素是否在一个集合中。当然在设计计算机软件时&#xff0c;我们也经常会判断一个元素是否在一个集合中。比如&#xff1a;在字处理软件中&#xff0c;…

排序(Sort)--【一】

排序&#xff0c;对于大家再熟悉不过了吧。我们之前在学习c语言的时候接触过的冒泡排序&#xff0c;选择排序等。今天给大家介绍两种新的排序。 1、直接插入排序 升序排列&#xff1a;将第一个数确定好&#xff0c;从下标为1的数开始插入&#xff0c;如果插入的数比前一个数大…

快速排序--全集

快速排序&#xff1a;一听名字就知道这种排序很快的&#xff0c;是吧&#xff1f;没错&#xff0c;它是一种效率比较高的排序算法。 快速排序采用的是分治的思想。 比如&#xff0c;将一串数中的一个元素作为基准&#xff0c;然后将比它小的数排在它的左边&#xff0c;比它大…

task_struct结构体查找

网上有很多解析task_struct结构体的文章&#xff0c;可是都没有说这个结构体到底在哪里&#xff1f; 这个结构体位于头文件 shced.h cd / find -name sched.h 显示结果如下 注意只有 位于内核中的include 才是正确的。 /usr/src/kernels/2.6.32-431.el6.i686/include/linux…

闹钟函数alarm()的解释与实践

alarm 定义 也称为闹钟函数&#xff0c;它可以在进程中设置一个定时器&#xff0c;当定时器指定的时间到时&#xff0c;它向进程发送SIGALRM信号。可以设置忽略或者不捕获此信号&#xff0c;如果采用默认方式其动作是终止调用该alarm函数的进程。 #include "head.h&quo…

Linux下如何设置权限让用户只删除自己的文件(粘滞位)

之前我们知道如何针对用户和用户组来设置文件权限。通常是用三个八进制来设置权限的&#xff0c;这里我要说的是&#xff0c;其实是由四个八进制表示的。其中第一个八进制我们通常是忽略的。第二个到第四个是对应于SUID,SGID,sticky-bit。 SUID&#xff1a;设置了SUID 位的文件…