深度探索new和delete
来源:互联网 发布:linux如何挂载磁盘 编辑:程序博客网 时间:2024/06/05 23:03
#include <stdio.h>#include <iostream>using namespace std;class A{public: virtual ~A() { cout << "in A" << endl; } int a;};class B : public A{public: ~B() { cout << "in B" << endl; } int b;};int main(int argc,char **argv, char**env){ while(*env) { //puts(*env); env++; } A *p = new B[1]; delete [] p; return 0;}
ⅠA *p = new B;delete p;in AⅡvirtualA *p = new B;delete p;in Bin AⅢA *p = new A[2];delete p;in AⅣA *p = new A[2];delete [] p;in Ain AⅤvirtualA *p = new B[2];delete [] p;如果sizeof(B)==sizeof(A)in Bin Ain Bin A如果sizeof(B)>sizeof(A)执行异常ⅥA *p = new B[2];delete [] p;in Ain A
Ⅰ~Ⅳ比较好理解,不再说明.
new B[2];开辟了一块内存,大小为2*sizeof(B),并对每个B都执行了构造函数,然后返回该内存块的起始地址.delete p;先对p指向的内存调用**p指向类型**的析构函数(如果p指向的类型的析构是virtual的,则会通过vptr调用派生类的析构函数,这是编译器在编译时扩充的操作),再free掉该内存块.delete [] p;对于new[],(比较可能)编译器会维护一个map,放置指针及数组元素的个数;执行delete [] p;时,会找到p对应的数组元素的个数,然后对p指向的内存块,依次调用**p指向类型**的析构函数(以sizeof(*p)为跃度).在Ⅴ第一种情况和Ⅵ中,并不涉及数据成员的操作,而且析构函数也没有使用class B的数据成员,所以没有问题;但是Ⅴ的第二种情况,由于析构函数是virtual的,会调用p->vptr[0]指向的析构函数,这倒也不打紧,但当为第二个数组元素执行析构的时候,(p+sizeof(A))->vptr[0]就有问题了,本应是(p+sizeof(B))->vptr[0]才对,取错误的vptr,自然造成了运行时错误.所以,下面的代码就不会出现运行时错误:virtualA *p = new B[1];delete [] p;
Ⅶ
A (*p)[3] = new A[2][3];
delete p;和delete [] p;均可以成功调用6次析构函数
大概编译器检测到p的类型是A(*)[],自动做了一些操作
写编译器的人真nb
参考:《深度探索C++对象模型》6.2节
0 0
- 深度探索new和delete
- 关于new和delete的编译器的内部实现---来自深度探索C++对象模型
- 深度探索c++对象模型之new和delete运算符介绍
- 探索c++的new和delete
- 深度剖析malloc、free和new、delete
- new, delete 和 new[] delete[]
- new、delete和new[]、delete[]
- 《深度探索C++对象模型》(二)C++,new,delete,构造/析构,临时对象
- new delete 关键字深度解析
- new和new[] 和delete 和delete[]
- 关于new和delete,new[] 和delete[]
- 关于new和delete,new[] 和delete[]
- 关于new和delete,new[] 和delete[]
- new和delete && new[] 和delete[]
- new/delete operator和operator new/delete
- C++ 中的 new/delete 和 new[]/delete[]
- C++中的new/delete和new[]/delete[]
- c++ new new[]和 delete delete[] 问题
- iOS Photos.framework 使用
- c++多个源文件共用一个全局变量(extern 的用法)
- python装饰器详解
- Delphi构造函数和析构函数
- scala =>符号含义总结
- 深度探索new和delete
- Log4Net简单应用
- 雅虎团队经验:网站页面性能优化的34条黄金守则
- 从源码分析RxJava在Android里线程切换的实现
- 解决UnicodeEncodeError: 'ascii' codec can't encode characters in position
- 关于fresco的属性介绍
- Jprofiler9.2使用介绍
- 不完全函数(待处理)
- SSH整合