delete和delete[]的区别
2015-11-09 14:50
661 查看
今天在看关于内存池的资料时,看到了placement new这个写法,先做一点简单介绍。
再说说主题,关于delete 和 delete[]的区别。一般的,在我们学习new这部分知识时会知道,new数组时我们使用delete[],new单个对象时,我们使用delete。那么为什么要这样呢?我是比较刨根问底的,所以我寻找了一些资料,在这里做一些总结,保留一些学习笔记,也希望帮助到他人。如果文章中有什么问题的话,还希望各位不吝指正。
那么,还是先来看例子,从例子中做总结。了解内存里比较特殊的自动可以看看这个Magic number。下面几个简单介绍截图中会出现的几个魔法数值
CDCDCDCD 该值标记未初始化过的堆内存
DDDDDDDD 该值标记被释放了的堆内存
FDFDFDFD 为堆分配内存前后的哨兵位.
class A
{
public:
~A()
{
cout << "destructor.." << endl;
}
};
class B
{
};
int main()
{
int *p_i = new int(45);
delete []p_i;
A *p_arr = new A[10];
delete []p_arr;
int *p_Iarr = new int[10];
delete p_Iarr;
B *p_B = new B();
delete p_B;
B *p_Barr = new B[10];
delete []p_Barr;
A *p_A = new A();
delete p_A;
return 0;
}
上面的图是new int(45);的内存数据,在哨兵位之间为这个int值。直接使用了delete
上面的图是new A[10];的内存数据,与其他不同的是我们定义了类A的析构函数,特别需要注意的是紫色标记的部分,分配对象数组的时候在真正数据之前还分配了4个字节的内存来保留数组元素的个数,在delete[]的时候取出这个数值就知道需要调用多少次析构函数。程序结束后打印了10次destructor..。这个必须使用delete[],如果使用delete,程序将就会crash.
上面的图是new int[10];的内存数据,这个也是new数组,与上面不同的是,对于内置类型int不需要调用析构函数,所以分配内存时就不需要多那个4个字节存数组元素个数。在这里我使用了delete,是可以的。使用delete[],也是可以的。
上面的图是new B();的内存数据,是单个对象,使用了delete。不需要多解释,主要看下面,与下面的数据做个比较。
上面的图是new B[10];的内存数据,是对象数组,与第二个不同的是,在类B中我们没有自定义他的析构函数,在分配内存的时候我们可以看到内存中也没有多分配那4个字节去存储数组元素个数。这里我们使用了delete[],事实上直接使用delete也是可以的。
由上面的几个数据分析我们可以得出结论:
1. new/delete、new[]/delete[] 配套使用总是没错的!
2. delete[]适用于带自定义析构函数的对象数组,如果没有自定义析构函数(在内存方面,析构函数主要用于释放对象中其他已分配的内存)也可以使用delete。
void *p = (void *)malloc(10000); A *i = new ((A *)p) A(); cout << i << " " << p << endl; free(p); p = NULL;这个简单的例子中就使用在指定内存地址中调用构造函数,而不分配内存。这种写法在内存池中比较常见,需要注意的可能就是最后内存的回收问题和销毁对象时,析构函数的调用,在这里不做赘述。而要处理好这些问题,就需要了解一下free/malloc,new/delete的在内存中的工作方式了。
再说说主题,关于delete 和 delete[]的区别。一般的,在我们学习new这部分知识时会知道,new数组时我们使用delete[],new单个对象时,我们使用delete。那么为什么要这样呢?我是比较刨根问底的,所以我寻找了一些资料,在这里做一些总结,保留一些学习笔记,也希望帮助到他人。如果文章中有什么问题的话,还希望各位不吝指正。
那么,还是先来看例子,从例子中做总结。了解内存里比较特殊的自动可以看看这个Magic number。下面几个简单介绍截图中会出现的几个魔法数值
CDCDCDCD 该值标记未初始化过的堆内存
DDDDDDDD 该值标记被释放了的堆内存
FDFDFDFD 为堆分配内存前后的哨兵位.
class A
{
public:
~A()
{
cout << "destructor.." << endl;
}
};
class B
{
};
int main()
{
int *p_i = new int(45);
delete []p_i;
A *p_arr = new A[10];
delete []p_arr;
int *p_Iarr = new int[10];
delete p_Iarr;
B *p_B = new B();
delete p_B;
B *p_Barr = new B[10];
delete []p_Barr;
A *p_A = new A();
delete p_A;
return 0;
}
</pre><p></p><p></p><pre>
上面的图是new int(45);的内存数据,在哨兵位之间为这个int值。直接使用了delete
上面的图是new A[10];的内存数据,与其他不同的是我们定义了类A的析构函数,特别需要注意的是紫色标记的部分,分配对象数组的时候在真正数据之前还分配了4个字节的内存来保留数组元素的个数,在delete[]的时候取出这个数值就知道需要调用多少次析构函数。程序结束后打印了10次destructor..。这个必须使用delete[],如果使用delete,程序将就会crash.
上面的图是new int[10];的内存数据,这个也是new数组,与上面不同的是,对于内置类型int不需要调用析构函数,所以分配内存时就不需要多那个4个字节存数组元素个数。在这里我使用了delete,是可以的。使用delete[],也是可以的。
上面的图是new B();的内存数据,是单个对象,使用了delete。不需要多解释,主要看下面,与下面的数据做个比较。
上面的图是new B[10];的内存数据,是对象数组,与第二个不同的是,在类B中我们没有自定义他的析构函数,在分配内存的时候我们可以看到内存中也没有多分配那4个字节去存储数组元素个数。这里我们使用了delete[],事实上直接使用delete也是可以的。
由上面的几个数据分析我们可以得出结论:
1. new/delete、new[]/delete[] 配套使用总是没错的!
2. delete[]适用于带自定义析构函数的对象数组,如果没有自定义析构函数(在内存方面,析构函数主要用于释放对象中其他已分配的内存)也可以使用delete。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- IE7降低内存和降低CPU的几个技巧
- oracle数据库删除数据Delete语句和Truncate语句的使用比较
- 如何高效的使用内存
- DOS下内存的配置
- some new eigrp feature
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- XP/win2003下发现1G的内存比512M还慢的解决方法
- delete from 表名与truncate table 表名区别
- drop,truncate与delete的区别
- mysql delete limit 使用方法详解
- MySQL DELETE语法使用详细解析
- ORACLE SQL-UPDATE、DELETE、INSERT优化和使用技巧分享
- sqlserver中delete、update中使用表别名和oracle的区别
- PowerShell实现动态获取当前脚本运行时消耗的内存