C语言中,存在三个用于动态分配内存的函数 :
- malloc函数
- 用途:分配一块未初始化的内存。
- 特点:分配的内存是未初始化的,可能是之前使用过的数据,需要手动初始化;如果分配失败,返回NULL。
- calloc函数
- 用途:分配并初始化一块指定大小的内存区域,所有位都被设置为 0。
- realloc函数
- 用途:重新分配一块内存区域的大小,可以增加或者减少原本的内存块。
- ptr表示之前通过动态内存分配的区域指针;new_size表示新的内存区域的大小;如果ptr为NULL则realloc行为类似于malloc,即分配一块新内存;如果new_size为0则行为类似于free,即回收一块内存;如果分配内存失败,返回NULL,并且保持原来的内存区域不变。
使用场景:
- :当你需要分配一块内存,并且不需要初始化或者需要非零的初始值时。
- :当你需要分配一块内存,并且希望这块内存的内容是确定的(例如,初始化为 0)。
- :当你需要改变已经分配的内存块的大小,或者在程序运行时动态调整内存使用时。
free函数用来释放通过malloc、calloc和realloc函数动态分配的内存区域;它只有一个参数——指向需要释放的内存的指针;没有任何返回值;当动态内存不再被需要时,应当使用free函数来释放这块内存避免内存泄漏。
C语言内存管理方式在C++里是可以继续使用的,但是C语言的动态内存分配函数在初始化方面有些无能为力。C语言的内存管理方式无法满足自定义类型的动态内存管理需要,类的初始化是需要调用构造函数,而C管理方式不能调用构造函数。
C++提出了新的内存管理方式:通过new和delete操作符进行动态内存管理。
申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],一定要匹配起来使用。
new/delete与malloc/free最大的区别就是,前者对于自定义类型除了开空间之外还会调用构造函数和析构函数。
new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数。new操作符在底层调用operator new 全局函数来申请空间,对于自定义类型还会调用构造函数。
看不懂没关系,operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间。
注意:这里的operator new不是重载的意思。
如果申请的是内置类型的空间,new和malloc,delete和free基本类似。不同的地方是:new/delete申请和释放的是单个元素的空间,new[]和delete[]释放的是连续空间,而且new在申请空间失败时会抛出异常。
- new的原理
- 调用operator函数申请空间。
- 在申请的空间上执行构造函数,完成对象的构造。
- delete的原理
- 在空间上执行析构函数,完成对象中资源的清理工作。
- 调用operator delete函数释放对象的空间。
- new T[N]的原理
- 调用operator new[]函数,在operator new[]函数中实际调用operator new函数完成N个对象空间的申请。
- 在申请的空间上执行N次构造函数。
- delete[]的原理
- 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理。
- 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间。
定位new表达式,是一种特殊的内存分配技术,它允许在已经分配的内存上构造对象。这种技术用于重用已经分配的内存,或者在特定的内存区域创建对象。
malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的是:
- malloc和和free都是函数,new和delete都是操作符。
- malloc申请的空间不会初始化,new可以初始化。
- malloc申请空间时,需要手动计算空间大小并传递,new只需要在后面跟上空间的类型即可,如果是多个对象,[]中指定对象的个数。
- malloc返回的类型是void*,使用时需要强制类型转换,new不需要,因为new返回的是空间的类型。
- malloc申请空间失败时,返回的是NULL,因此使用时必须判空;new不需要判空,但是new需要捕获异常。
-
申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理
内存泄漏是指因为疏忽或者错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段的控制,因而造成了内存的浪费。
内存泄漏会导致长期运行的程序响应越来越慢,最终卡死。
- 堆内存泄漏(Heap Leak)
堆内存是指通过malloc/calloc/realloc/new等从堆中分配的一块内存,用完之后必须通过调用相应的free和delete释放。加入程序的设计错误导致没有被释放,那么这部分空间将无法再被使用,导致堆内存泄露。
- 系统资源泄漏
指程序使用系统分配的资源,比如套接字、文件描述符、管道等没有使用相应的函数释放掉,导致系统资源的浪费,严重的可导致系统性能降低,系统执行不稳定。
delete[]是怎么知道要调用多少次delete函数的呢?
在这段代码中,实际上new[]不只申请了10个类类型的大小,它额外申请了4个字节用来存放开辟空间的数目,这四个字节在返回的地址之前。
到此这篇c++单向链表(c++单向链表的基本操作)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/cjjbc/69266.html