new/delete 和 new[]/delete[]

new/delete 和 new[]/delete[]

本文以如下的base为例,进行调试和验证,new 和delete,以及new[]和delete[]都是标准库函数,通过重载上述四个函数。

1 class base{ 
 2 public: 
 3     base(void){ 
 4         printf("base\n"); 
 5     } 
 6 
 7     static void* operator new(size_t cb,int nBlockUse,const char * szFileName,int nLine){ 
 8         printf("operator new\n"); 
 9         return ::operator new(cb); 
10     } 
11 
12     static void* operator new[](size_t cb,int nBlockUse,const char * szFileName,int nLine){ 
13         printf("operator new[]\n"); 
14         return ::operator new(cb); 
15     } 
16 
17     void operator delete(void* p,size_t ){ 
18         printf("operator delete\n"); 
19     } 
20 
21     void operator delete[](void* p,size_t ){ 
22         printf("operator delete[]\n"); 
23     } 
24 
25     ~base(void){ 
26         printf("~base\n"); 
27     } 
28 };

1 new和delete表达式

1.1 new 表达式

base* pb = new base;

执行new表达式时,实际发生了三个步骤:

  • 首先,调用名为operator new的标准库函数(可以重载),其功能是分配足够大的原始类型的内存,以保存指定类型的对象;
  • 然后,运行该类型的一个构造函数,用指定初始化式构造对象;
  • 最后,返回指向新分配并构造的对象指针。

上述语句输出的是:

operator new 
base

1.2 delete表达式

delete pb;

执行delete表达式时,实际发生了两个步骤:

  • 首先,对指针指向的对象运行适当的析构函数;
  • 然后,通过调用名为operator new的标准库函数(可以重载)释放该对象所用内存。

上述语句输出的是:

~base 
operator delete

2 new[]和delete[]表达式

2.1 new[]表达式

base* pb = new base[3];

执行new[]表达式时,实际上发生了三个步骤:

  • 首先,调用名为operator new[] 的标准库函数(可以重载)。其功能是分配足够大的原始类型的内存,并在最低地址用四个字节来保存创建数组的大小。
  • 然后,通过上述数组的大小,运行该类型的个构造函数;
  • 最后,返回数组的是数组对象的指针,而不是所有分配对象空间的的起始地址。

上述语句输出:

operator new[] 
base 
base 
base

2.2 delete[]表达式

delete[] p;

执行delete[]表达式,实际上发生了两个步骤:

  • 首先,根据数组最低地址的4个字节空间,获得数组的大小,然后调用多个析构函数;
  • 然后,调用operator delete[] 标准库函数(可以重载)释放该对象所有内存。

上述语句输出:

operator new[] 
base 
base 
base

注意:只有在中括号出现时,编译器才寻找数组的维度,否则它便假设只有单独一个objects要被删除。

3 特殊出现

正确使用的配对是new与delete,以及new[]与delete[]成对出现,这样才能保证内存空间的正确释放和析构函数正确的调用,但有时也会出现它们之间不是正确的配对,如下几种情况

3.1 new与delete[]错误配对

base* pb = new base; 
delete[] pb;

输出:

operator new 
base 
~base 
operator delete

从上述结果得到:当new一个对象,而用delete[]进行释放对象时,这与正常new和delete配对使用时,输出的内容是一样的,即释放的对象。

3.2 new[]与delete错误配对

base* p = new base[3]; 
delete p;

输出:

operator new[] 
base 
base 
base 
~base 
operator delete

从上述结果得到:当使用new[]创建了多个对象,但是使用delete释放对象时,只释放的第一个对象。其它元素仍然存在——虽然其相关的内存已经被要求归还了。

时间: 2024-08-05 19:34:21

new/delete 和 new[]/delete[]的相关文章

new/delete和new[]/delete[]的底层调用和简单实现

在使用new的时候做了两件事: 1.调用operator new分配空间 2.调用构造函数初始化对象 在使用delete的时候也做了两件事: 1.调用析构函数清理对象 2.调用operator delete函数释放空间 在使用new[N]的时候也做了两件事: 1.调用operator new分配空间 2.调用N次构造函数初始化N个对象 在使用delete[]的时候也做了两件事: 1.调用N次析构函数清理N个对象 2.调用operator delete函数释放空间 定位new表达式:定位new表达

ios ASIHttpRequest库进行DELETE操作时delete带有参数表单的使用方法

1,普通的DELETE只需加上下述一句code: [request setRequestMethod:@"DELETE"]; 2,附带有参数表单的情况(一次删除请求): ASIFormDataRequest *request; NSURL *baseURL = [NSURL URLWithString:@"http://www.baidu.com/xx/"]; request = [ASIFormDataRequest requestWithURL:baseURL]

PHP MySQL Delete From 之 Delete

删除数据库中的数据 DELETE FROM 语句用于从数据库表中删除记录. 语法 DELETE FROM table_name WHERE column_name = some_value 注释:SQL 对大小写不敏感.DELETE FROM 与 delete from 等效. 为了让 PHP 执行上面的语句,我们必须使用 mysql_query( 函数.该函数用于向 SQL 连接发送查询和命令. 例子 稍早时,我们在本教程中创建了一个名为 "Persons" 的表.它看起来类似这样:

C# GridView Edit & Delete, 点击Delete的时候弹出确认框

1. 使用GridView自带属性ShowEditButton和ShowDeleteButton,均设为True  <Columns> ... <asp:CommandField ShowEditButton="True" ShowDeleteButton="True"></asp:CommandField> </Columns> 则在GridView指定列的位置会显示Edit和Delete的LinkButton 2.

HBase编程 API入门之delete.deleteColumn和delete.deleteColumns区别

delete.deleteColumn和delete.deleteColumns区别是 deleteColumn是删除某一个列簇里的最新时间戳版本. delete.deleteColumns是删除某个列簇里的所有时间戳版本. hbase(main):020:0> desc 'test_table'Table test_table is ENABLED test_table COLUMN FAMILIES DESCRIPTION {NAME => 'f', DATA_BLOCK_ENCODING

【转】浅谈 C++ 中的 new/delete 和 new[]/delete[]

原文 在 C++ 中,你也许经常使用 new 和 delete 来动态申请和释放内存,但你可曾想过以下问题呢? new 和 delete 是函数吗? new [] 和 delete [] 又是什么?什么时候用它们? 你知道 operator new 和 operator delete 吗? 为什么 new [] 出来的数组有时可以用 delete 释放有时又不行? - 如果你对这些问题都有疑问的话,不妨看看我这篇文章. new 和 delete 到底是什么? 如果找工作的同学看一些面试的书,我相

delete p和delete [] p的区别(转)

operator new 和 operator delete函数有两个重载版本,每个版本支持相关的new表达式和delete表达式: void* operator new (size_t); // allocate an objectvoid* operator new [] (size_t); // allocate an array void operator delete (void*); // free an ojectvoid operator delete [] (void*); /

Oracle delete input与delete all input

oracle官方文档提示:If you had specified DELETE INPUT rather than DELETE ALL INPUT, then RMAN would have only deleted the specific archived redo log files that it backed up. For example, RMAN would delete the logs in /arc_dest1 if these files were used as t

RMAN 中delete exipired 和 delete obsolete 的区别

elete expired If you run CROSSCHECK, and if RMAN cannot locate the files, then it updates their records in the RMAN repository to EXPIRED status. You can then use the DELETE EXPIRED command to remove records of expired backups and copies from the RMA