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,一经查实,立即删除!

相关文章

vim 的配置文件 #vim ~/.vimrc

set hlsearch set backspace2 set nu set showmode set ruler set autoindent syntax on set smartindent set tabstop4 set shiftwidth4 set expandtab imap { {}iV

关于tornado的异步耗时操作假设

tornado 如果遇到耗时的操作,可不可以这样 把耗时操作放在一个由 python进程池维护的 pool中, 用 webapi封装起来, 然后tornado 接收客户端请求后,遇到耗时操作就 与访问另一个webapi , webapi去调用进程池 这种模型不…

Stack/Queue与Vector/List的联系

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

利用SetConsoleTextAttribute函数设置控制台颜色

原文出处&#xff1a; https://blog.csdn.net/odaynot/article/details/7722240 混合颜色 #include <windows.h> #include <iostream> using namespace std;int main() {HANDLE hOut;hOut GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTextAttribute(hOut,FOREG…

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

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

SetConsoleCursorPosition光标的位置控制

SetConsoleCursorPosition是一个计算机函数&#xff0c;如果用户定义了 COORD pos&#xff0c;那么pos其实是一个结构体变量&#xff0c;其中X和Y是它的成员&#xff0c; 通过修改pos.X和pos.Y的值就可以实现光标的位置控制。 复制粘贴运行一下&#xff0c;你就明白代码什么意…

用栈和递归求解迷宫问题

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

exit(0) return区别

1. return是返回函数调用&#xff0c;如果返回的是main函数&#xff0c;则为退出程序。 exit是在调用处强行退出程序&#xff0c;运行一次程序就结束&#xff0c; 无论写在那里&#xff0c;都是程序推出&#xff0c;括号里的数字0,1,-1会被写入环境变量ERRORLEVEL&#xff0c…

electron 5.0.3版本 改动的地方

BrowserWindow.getFocusedWindow 1. BrowserWindow.getFocusedWindow getFocusedWindow 已经不是一个方法了&#xff0c; 这个简单的问题解决了半天&#xff0c;因为我看文档上 还是当一个方法来调用&#xff0c; 文档没有正确更新&#xff0c;实际上已经变成了一个属性&#…

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

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

【转】浅析task_struct结构体

https://blog.csdn.net/peiyao456/article/details/54407343

electron 主进程与渲染进程 渲染进程与渲染进程 之间的通信

主进程与渲染进程之间的通信 这是渲染进程 // 渲染进程执行主进程里面的方法&#xff0c;主进程给渲染进程反馈处理结果 。 var sendreplayDomdocument.querySelector(#sendreplay); sendreplayDom.onclickfunction(){// alert(1213)//渲染进程给主进程广播数据ipcRenderer.se…

centos升级之gcc 升级 gcc-7.3.0安装

更新于&#xff1a;2018_7_28 安装时间非常非常久&#xff0c;我最快一次40分钟&#xff0c;最长一次两个小时 cd / wget ftp.gnu.org/gnu/gcc/gcc-7.3.0/gcc-7.3.0.tar.gz tar -zxvf gcc-7.3.0.tar.gz cd gcc-7.3.0 ./contrib/download_prerequisites mkdir build cd …

[数据结构]用插入排序和选择排序的思想实现优先级队列

一、问题概述 优先级队列的定义&#xff1a; 优先级队列不同于普通的队列&#xff0c;普通的队列具有先进先出的原则&#xff0c;而优先级队列是选择优先级最高的先出队。那么&#xff0c;如何模拟实现优先级队列呢&#xff1f;在这里&#xff0c;我们将较大的值作为优先级较高…

node.js https 模块设置请求头等信息

// https://www.iqiyi.com/v_19rs789v28.html var fs require(fs); var https require(https); var option{rejectUnauthorized: false,hostname:www.iqiyi.com,path:/,headers:{Accept:*/*,Accept-Encoding:utf-8, //这里设置返回的编码方式 设置其他的会是乱码Accept-Lang…

centos升级之vim vim8.0安装

YCM安装攻略&#xff1a;https://blog.csdn.net/csdn_kou/article/details/81213935 卸载旧的vim yum remove vim* -y 一、源码编译安装vim8.0 配置epel源 yum install epel-release 安装python3,以及vim8.0编译环境 yum install -y gcc python34 python34-devel ncurses…

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

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

centos升级之内核kernel

yum update kernel yum update && yum upgrade # rpm –import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org # rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm # yum –disablerepo”*” –enablerepo”elrepo-kernel” list ava…