C++类和new、delete操作符和堆和栈内存的分配

如果你是Java、C#、PHP程序员,那么会对 new 非常熟悉,在这些编程语言中,只能通过 new 来创建对象。
在C++中,你可以像定义变量一样来创建对象,如:
  1. Student stu; //对象已被实例化,已分配内存空间,可以使用了
  2. stu.say(); //调用成员函数
这种情况下,系统会在栈区为对象分配内存。栈区是内存中的一块区域,由系统自动分配和释放,程序员无法操控,一般用来存放函数的参数值、局部变量、局部对象等。

当发生函数调用时,系统将函数参数、局部变量、局部对象依次压入栈区;函数执行结束,再按照先进后出的原则将它们弹出(销毁)。

对于大部分程序,这不会有什么问题。但当你希望在函数调用结束前销毁对象时,你是无能为力的。或者你希望通过 for 循环来创建多个对象,这种方法同样也做不到。

这个时候 new 和 delete 就派上了用场:使用 new 创建的对象,可以在任意时刻通过 delete 销毁,而且只需要一个指针指向它。

以前面的 Student 类为例,可以这样来动态创建对象:
new Student;
也可以使用构造函数:
new Student("小明", 15, 90.5f);
这样,就在堆区为对象分配了内存,并调用了构造函数。

但是此时程序员还无法访问这个对象,因为这个对象既没有名字,也没有指针指向它。这种对象称为 匿名对象 ,它确实存在,但无法访问。

用一个指针来指向Student类的对象:
Student *pStu;
pStu = new Student("小明", 15, 90.5f);
或者:
Student *pStu = new Student("小明", 15, 90.5f);

当不再需要对象时,可以通过 delete 销毁:
delete pStu;
这样,就释放掉了对象占用的内存,并调用了析构函数。

需要说明的是:new 在堆区为对象分配内存。与栈区不同的是,堆区内存由程序员分配和释放,系统不会自动销毁,即使函数调用结束了,仍然会保留堆区内存。如果程序员不主动回收堆区内存,那么只能在程序运行结束后由操作系统回收。

为了避免内存泄露,强烈建议 new 和 delete 成对出现,及时销毁不再需要的对象。

例如,下面的代码会造成严重的内存泄露:
  1. #include <iostream>
  2. #include <cstdlib>
  3. using namespace std;
  4. class Demo{
  5. private:
  6. double n;
  7. double m;
  8. int i;
  9. };
  10. void func(){
  11. Demo *p = new Demo;
  12. }
  13. int main(){
  14. int i;
  15. for(i=1; i<=1000000; i++){
  16. func();
  17. }
  18. system("pause");
  19. return 0;
  20. }
当程序运行到 system("pause"); 语句时,你可以打开任务管理器,会发现这个小小的程序竟然占用了 32M 内存。

这是因为每次调用 func 函数,都会创建一个对象,并用 p 指向它。函数运行结束,仅仅释放了指针变量 p 占用的内存,而没有释放 p 所指向的对象占用的内存。

如果在 func 函数中不回收对象内存,那么你将永远无法回收,只能等到程序运行结束由操作系统回收,这就是典型的内存泄露。

另外注意,C语言中的 malloc、free 函数不能用来为对象分配和释放内存。请看下面的例子:
  1. #include <iostream>
  2. using namespace std;
  3. class Demo{
  4. public:
  5. Demo();
  6. ~Demo();
  7. };
  8. Demo::Demo(){
  9. cout<<"Constructor"<<endl;
  10. }
  11. Demo::~Demo(){
  12. cout<<"Destructor"<<endl;
  13. }
  14. int main(){
  15. cout<<"------new------"<<endl;
  16. Demo *p1 = new Demo; //创建一个对象
  17. Demo *p2 = new Demo[5]; //创建一组对象
  18. cout<<"------malloc------"<<endl<<endl;
  19. Demo *p3 = (Demo*)malloc(sizeof(Demo));
  20. cout<<"------delete------"<<endl;
  21. delete p1; //销毁一个对象
  22. delete[] p2; //销毁一组对象
  23. cout<<"------free------"<<endl;
  24. free(p3);
  25. return 0;
  26. }
运行结果:
------new------
Constructor
Constructor
Constructor
Constructor
Constructor
Constructor
------malloc------

------delete------
Destructor
Destructor
Destructor
Destructor
Destructor
Destructor
------free------

从程序运行结果可以看出:malloc 虽然分配了内存,但没有调用构造函数;free 虽然释放了内存,但也没有调用析构函数。

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

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

相关文章

从B 树、B+ 树、B* 树谈到R 树

作者&#xff1a;July、weedge、Frankie。编程艺术室出品。 说明&#xff1a;本文从B树开始谈起&#xff0c;然后论述B树、B*树&#xff0c;最后谈到R 树。其中B树、B树及B*树部分由weedge完成&#xff0c;R 树部分由Frankie完成&#xff0c;全文最终由July统稿修订完成。 出…

在CentOS中安装gcc配置c语言开发环境(转)

From:http://hsl46346.blog.163.com/blog/static/17764050201062074955358/ From: CentOS 5.4 下gcc和gcc-c的光盘 rpm 安装方式 From: centos 安装 java CentOs是linux系统的一种&#xff0c;只要该操作系统安装了gcc软件包&#xff0c;就可以在linux操作系统中进行C语言程序设…

纯IPv6环境App适配的坑

来源&#xff1a;伯乐在线专栏作者 - MrPeak 链接&#xff1a;http://ios.jobbole.com/86580/ 苹果从2016年6月1号开始&#xff0c;强制所有app必须支持纯IPv6的网络环境。这项举措将对IPv6的普及起到一定的推动作用&#xff0c;也体现了Apple作为国际大厂的担当。 大部分App由…

使用Visual Studio 创建新的Web Part项目

使用Visual Studio 创建新的Web Part项目 Web Part是你将为SharePoint创建的最常见的对象之一。它是平台构建的核心基块。1. 管理员身份打开Visual Studio&#xff0c;新建空白SharePoint项目。命名WroxSPProject&#xff0c;点击确定。部署为场解决方案&#xff0c;点击完成。…

聊一聊Yarp结合Nacos完成服务发现

背景 Yarp 这个反向代理出来后&#xff0c;相信还是有不少人在关注的。在 Yarp 中&#xff0c;反向代理的配置默认也是基于配置文件的&#xff0c;也有不少大佬已经把这个配置做成了数据库配置可视化界面。仔细想了想&#xff0c;做成数据库配置&#xff0c;好像只是便于配置的…

相亲对象能有多油腻......

1 冰起来再烧&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 还没从年假清醒的我&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 孙悟空为啥没被人收去当坐骑&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼4 成年人的潜台词&#xff08;素材…

C++之char*,const char*和string的相互转换

1. string转const char*string s "abc";const char* c_s s.c_str(); 2. const char*转string直接赋值即可const char* c_s "abc";string s(c_s); 3. string转char*string s "abc";char* c;const int len s.length();c new char[len1];strc…

教你如何迅速秒杀掉:99%的海量数据处理面试题

教你如何迅速秒杀掉&#xff1a;99%的海量数据处理面试题 作者&#xff1a;July 出处&#xff1a;结构之法算法之道blog 前言 一般而言&#xff0c;标题含有“秒杀”&#xff0c;“99%”&#xff0c;“史上最全/最强”等词汇的往往都脱不了哗众取宠之嫌&#xff0c;但进一步来讲…

poj 1986 Distance Queries

LCA 题意&#xff1a;LCA模板题&#xff0c;输入n和m&#xff0c;表示n个点m条边&#xff0c;下面m行是边的信息&#xff0c;两端点和权&#xff0c;后面的那个字母无视掉&#xff0c;没用的。接着k&#xff0c;下面k个询问lca&#xff0c;输出即可 有人说要考虑不连通的情况&a…

【.NET 遇上 GraphQL】 ChilliCream 平台介绍

ChilliCreamhttps://chillicream.com/https://github.com/ChilliCream/hotchocolateChilliCream 平台包含了四个产品, Hot Chocolate, Banana Cake Pop, Strawberry Shake, 平台提供开发人员工具和服务以加快整个开发过程。Hot ChocolateHot Chocolate 是 .NET 平台下的一个开源…

.NET 的 WebSocket 开发包比较

编者按 本文出现在第三方产品评论部分中。在这一部分的文章只提供给会员&#xff0c;不允许工具供应商用来以任何方式和形式来促销或宣传产品。请会员报告任何垃圾信息或广告。 Web项目常常需要将数据尽可能快地推送给客户&#xff0c;必要时无需等待客户端请求。对于与用户之间…

《CMake实践》笔记二:INSTALL/CMAKE_INSTALL_PREFIX

《CMake实践》笔记一&#xff1a;PROJECT/MESSAGE/ADD_EXECUTABLE 《CMake实践》笔记二&#xff1a;INSTALL/CMAKE_INSTALL_PREFIX 《CMake实践》笔记三&#xff1a;构建静态库与动态库 及 如何使用外部共享库和头文件 四、更好一点的Hello World 没有最好&#xff0c;只有更好…

14年前,林国强院士发现自己学生论文无法重复后,是这样处理的

全世界只有3.14 % 的人关注了爆炸吧知识本文转自&#xff1a;iNature让我们把时间拨回至 2007 年 3 月&#xff0c;当年&#xff0c;一封以林国强院士的名义发表的公开信&#xff0c;在网络上流传。信中披露&#xff0c;林院士发现自己的一名博士生发表在权威期刊《美国化学会志…

C++ char[] 与 string 转换

处理档案资料&#xff0c;最常使用 char[] 或 string 来储存字串&#xff0c;前者是 字元阵列 &#xff0c;为C所拥有&#xff0c;当然C也可以使用&#xff1b;而后者是C独有的 字串类别 &#xff0c;可以产生字串物件。在使用C处理字串时&#xff0c;时常会char[]和string互转…

支持向量机通俗导论(理解SVM的三层境界)

支持向量机通俗导论&#xff08;理解SVM的三层境界&#xff09; 作者&#xff1a; July &#xff1b; 致谢&#xff1a; pluskid、 白石、J erryLead。出处&#xff1a;结构之法算法之道 blog 。 前言 动笔写这个支持向量机(support vector machine)是费了不少劲和困难的&#…

WPF 实现加速小火箭~

WPF开发者QQ群&#xff1a; 340500857由于微信群人数太多入群请添加小编微信号yanjinhuawechat 或 W_Feng_aiQ 邀请入群需备注WPF开发者 PS&#xff1a;有更好的方式欢迎推荐。01—代码如下一、创建 SpeedRocketsExample.xaml 代码如下。<Window x:Class"WPFDevelopers…

第二十四天 多维数组

经过前面对一维数组和二维数组的学习&#xff0c;我们充分的掌握了数组的定义和使用&#xff0c;接下来我们该学习的是&#xff1a;多维数组。比较简单的方法&#xff0c;想要提高数组的维数只要在声明的时候在索引多加一个中括号即可。比如&#xff1a;我们要声明三维数组那么…

最懂男人心的内裤,戳100个洞透气,超舒服

▲ 点击查看有什么日用品&#xff0c;需要盆友们时不时就经常补货买买买的&#xff1f;除了家里的酱油、纸巾、沐浴露&#xff0c;还有一样hin重要&#xff0c;那就是内裤&#xff01;除了洗澡的空挡&#xff0c;内裤就一直穿在身上&#xff0c;可以说内裤是比女友还亲、比手机…

搬家到此,嘿嘿

希望能够把遇到的技术问题给记录起来&#xff0c;给我加油吧&#xff01; 之前一直在网易博客上记录&#xff0c;刚搬到此地&#xff0c;尽快习惯下来啦转载于:https://www.cnblogs.com/lwjlss/p/5682533.html

C++ throw:抛出自己的异常

throw 是C中的关键字&#xff0c;用来抛出异常。如果不使用 throw 关键字&#xff0c;try 就什么也捕获不到&#xff1b;上节提到的 at() 函数在内部也使用了 throw 关键字来抛出异常。throw 既可以用在标准库中&#xff0c;也可以用在自定义的函数中&#xff0c;抛出我们期望的…