C++中的new和delete

内容来自互联网,做下整理,备忘

虽然为了与C语言兼容,C++仍保留malloc和free函数,但建议用户不用malloc和free函数,而用new和delete运算符。new运算符的例子:

new int;//开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针)
new int(100);//开辟一个存放整数的空间,并指定该整数的初值为100,返回一个指向该存储空间的地址
new char[10];//开辟一个存放字符数组(包括10个元素)的空间,返回首元素的地址
new int[5][4];//开辟一个存放二维整型数组(大小为5*4)的空间,返回首元素的地址
float *p=new float (3.14159);//开辟一个存放单精度数的空间,并指定该实数的初值为//3.14159,将返回的该空间的地址赋给指针变量p

new运算符使用的一般格式为
   new 类型 [初值]


用new分配数组空间时不能指定初值。如果由于内存不足等原因而无法正常分配空间,则new会返回一个空指针NULL,用户可以根据该指针的值判断分配空间是否成功。

delete运算符使用的一般格式为
   delete [ ] 指针变量


例如要撤销上面用new开辟的存放单精度数的空间(上面第5个例子),应该用
   delete p;
前面用“new char[10];”开辟的字符数组空间,如果把new返回的指针赋给了指针变量pt,则应该用以下形式的delete运算符撤销该空间:
   delete [] pt;//在指针变量前面加一对方括号,表示是对数组空间的操作

-----------------------------------------------------------------------------------------

1 、对象的分类

①        全局对象( Global Object )                     Controlled by System

②        局部对象( Local Object )                      Controlled by System

③        动态生成对象( Dynamically Allocated Object )           controlled by programmer

 

2 、动态对象的生与死

①        创建: new

②        销毁: delete

 

3 、动态对象的创建的地址

         内存池( memory pool )中的一块程序自由存储区域( free store area ),实际上就是通常所说的堆( Heap )

 

4 、动态对象的存在形式

①        简单对象( single object )

②        对象数组( array object )

③        The placement new express

 

5 、动态对象的使用

①        动态对象的操纵

动态对象没有名称,而是返回分配对象的指针地址,所有操作都是通过指针间接完成

②        动态对象的初始化

动态对象分配的内存区域是没有初始化过的,里面存在的是随机数据

 

6 、动态对象及指针的生命周期

①        动态对象

持续时间为 new ç è delete

②        指针

根据其自身类型决定(全局 / 局部)

 

7 、 delete 的使用

例 1 :

         int  *pi=new int;

         if(pi!=0){

           delete pi;

}      

该段程序运行起来是没有问题的,但是却存在画蛇添足的一笔: if(pi!=0)

         原因是, delete 会自动完成这个测试,如果显式地测试,将会多执行一次测试。所以说完全没有必要。

        

         例 2 :

                   pointer=0;                    // 不指向任何对象

                   delete pointer;              // 没有必要

        

         总结:

也许会有人觉得两个例子似乎有点矛盾,其实上述例程的意思是:

①        当我们不知道一个对象内存是否已经释放的时候,直接 delete 即可,是没有任何问题的;额外的判断完全没有必要,反而会增加系统的工作量。

②        当我们明确地知道对象指针 ==NULL 时,表明已经释了对象。这时就可以少写一行代码了。当然如果有人想看看计算机又没有不良反应,另当别论。

同时也证明了①,删除一个 NULL 对象是没有任何问题的

 

8 、动态内存分配常见错误

①        内存泄露

我想这个问题对 C++ 程序员来说,是非常熟悉的。

u        根源是:?

简短的回答: new 与 delete 没有配对使用

明白了吗?还不明白? next :

                  只给对象分配了内存,但是直到关闭程序的时候,都还没有向对象要回那块内存。

u        怎样发现?

Ø         Vc IDE 中, debug 状态,程序结束时 output 窗口的 Detect Memory leak !

Ø         使用工具软件,如: BoundCheck

 

u        如何避免?

呵呵,知道了根源就应该知道该咋办了。。。

        

②        读 / 写已经删除的对象(内存)

当对象 delete 以后,对象内存被系统回收,其指针就指向到一块非法的内存。如果再对该对象指向内存操作就会导致不可预知的错误。因此,通常的做法是 delete 之后,立即赋 NULL

 

③        内存 corruptted

很熟悉,是吧?不要着急,请听我慢慢道来。。。

         未命名.bmp

根源:

u        ptrA 与 ptrB 都指向同一块内存

u        通过 ptrA 释放内存 Mem0 , Mem0 分配给其它对象 ptrC

u        ptrB 释放内存 , Mem0 存储的 ptrC 指向的新对象就被破坏掉了。

u        再次对 ptrC 操作就会出错

 

④        对象类型错误

例:

CDialog  dlg=new CDialog ;

delete dlg ;

                  你能发现什么不对吗?

                   提示一下, debug 运行会发现 mem leak !

                   知道了吧, what ?

                  就是 delete dlg 。                   

在 5.1 中说过, new 返回的是指针。所以应该将 dlg 声明为 CDialog* 类型。


-----------------------------------------------------------------------------------

在嵌入式系统中使用C++的一个常见问题是内存分配,即对new 和 delete 操作符的失控。

具有讽刺意味的是,问题的根源却是C++对内存的管理非常的容易而且安全。具体地说,当一个对象被消除时,它的析构函数能够安全的释放所分配的内存。这当然是个好事情,但是这种使用的简单性使得程序员们过度使用new 和 delete,而不注意在嵌入式C++环境中的因果关系。并且,在嵌入式系统中,由于内存的限制,频繁的动态分配不定大小的内存会引起很大的问题以及堆破碎的风险。

作为忠告,保守的使用内存分配是嵌入式环境中的第一原则。

但当你必须要使用new 和delete时,你不得不控制C++中的内存分配。你需要用一个全局的new 和delete来代替系统的内存分配符,并且一个类一个类的重载new 和delete。

一个防止堆破碎的通用方法是从不同固定大小的内存持中分配不同类型的对象。对每个类重载new 和delete就提供了这样的控制。

重载全局的new 和delete 操作符

可以很容易地重载new 和 delete 操作符,如下所示:

void * operator new(size_t size)
{
 void *p = malloc(size);
 return (p);
}
void operator delete(void *p);
{
 free(p);
}

这段代码可以代替默认的操作符来满足内存分配的请求。出于解释C++的目的,我们也可以直接调用malloc() 和free()。

也可以对单个类的new 和 delete 操作符重载。这是你能灵活的控制对象的内存分配。

class TestClass {
 public:
  void * operator new(size_t size);
  void operator delete(void *p);
  // .. other members here ...
};
void *TestClass::operator new(size_t size)
{
 void *p = malloc(size); // Replace this with alternative allocator
 return (p);
}
void TestClass::operator delete(void *p)
{
 free(p); // Replace this with alternative de-allocator
}

所有TestClass 对象的内存分配都采用这段代码。更进一步,任何从TestClass 继承的类也都采用这一方式,除非它自己也重载了new 和 delete 操作符。通过重载new 和 delete 操作符的方法,你可以自由地采用不同的分配策略,从不同的内存池中分配不同的类对象。

为单个的类重载 new[ ] 和 delete[ ] 必须小心对象数组的分配。你可能希望调用到被你重载过的new 和 delete 操作符,但并不如此。内存的请求被定向到全局的new[ ]和delete[ ] 操作符,而这些内存来自于系统堆。

C++将对象数组的内存分配作为一个单独的操作,而不同于单个对象的内存分配。为了改变这种方式,你同样需要重载new[ ] 和 delete[ ]操作符。

class TestClass {
 public:
  void * operator new[ ](size_t size);
  void operator delete[ ](void *p);
  // .. other members here ..
};
void *TestClass::operator new[ ](size_t size)
{
 void *p = malloc(size);
 return (p);
}
void TestClass::operator delete[ ](void *p)
{
 free(p);
}
int main(void)
{
 TestClass *p = new TestClass[10];
 // ... etc ...
 delete[ ] p;
}

但是注意:对于多数C++的实现,new[]操作符中的个数参数是数组的大小加上额外的存储对象数目的一些字节。在你的内存分配机制重要考虑的这一点。你应该尽量避免分配对象数组,从而使你的内存分配策略简单。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于微信小程序的家政服务预约系统采用PHP语言和微信小程序技术,数据库采用Mysql,运行软件为微信开发者工具。本系统实现了管理员和客户、员工三个角色的功能。管理员的功能为客户管理、员工管理、家政服务管理、服务预约管理、员工风采管理、客户需求管理、接单管理等。客户的功能为查看家政服务进行预约和发布自己的需求以及管理预约信息和接单信息等。员工可以查看预约信息和进行接单。本系统实现了网上预约家政服务的流程化管理,可以帮助工作人员的管理工作和帮助客户查询家政服务的相关信息,改变了客户找家政服务的方式,提高了预约家政服务的效率。 本系统是针对网上预约家政服务开发的工作管理系统,包括到所有的工作内容。可以使网上预约家政服务的工作合理化和流程化。本系统包括手机端设计和电脑端设计,有界面和数据库。本系统的使用角色分为管理员和客户、员工三个身份。管理员可以管理系统里的所有信息。员工可以发布服务信息和查询客户的需求进行接单。客户可以发布需求和预约家政服务以及管理预约信息、接单信息。 本功能可以实现家政服务信息的查询和删除,管理员添加家政服务信息功能填写正确的信息就可以实现家政服务信息的添加,点击家政服务信息管理功能可以看到基于微信小程序的家政服务预约系统里所有家政服务的信息,在添加家政服务信息的界面里需要填写标题信息,当信息填写不正确就会造成家政服务信息添加失败。员工风采信息可以使客户更好的了解员工。员工风采信息管理的流程为,管理员点击员工风采信息管理功能,查看员工风采信息,点击员工风采信息添加功能,输入员工风采信息然后点击提交按钮就可以完成员工风采信息的添加。客户需求信息关系着客户的家政服务预约,管理员可以查询和修改客户需求信息,还可以查看客户需求的添加时间。接单信息属于本系统里的核心数据,管理员可以对接单的信息进行查询。本功能设计的目的可以使家政服务进行及时的安排。管理员可以查询员工信息,可以进行修改删除。 客户可以查看自己的预约和修改自己的资料并发布需求以及管理接单信息等。 在首页里可以看到管理员添加和管理的信息,客户可以在首页里进行家政服务的预约和公司介绍信息的了解。 员工可以查询客户需求进行接单以及管理家政服务信息和留言信息、收藏信息等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值