class A { public: A() :a(1), b(1.11){} private: int a; double b; }; int main() { A * ptr = (A*)malloc(sizeof(A)); return 0; }
在return处设置断点,观看ptr所指内存的内容:
可以看出A的默认构造函数并没有被调用,因为数据成员a,b的值并没有得到初始化,这也是上面我为什么说使用malloc/free来处理C++的自定义类型不合适,其实不止自定义类型,标准库中凡是需要构造/析构的类型通通不合适。
而使用new来分配对象时:
int main() { A * ptr = new A; }
查看程序生成的汇编代码可以发现,A的默认构造函数被调用了:
6.对数组的处理C++提供了new[]与delete[]来专门处理数组类型:
A * ptr = new A[10];//分配10个A对象
使用new[]分配的内存必须使用delete[]进行释放:
delete [] ptr;
new对数组的支持体现在它会分别调用构造函数函数初始化每一个数组元素,释放对象时为每个对象调用析构函数。注意delete[]要与new[]配套使用,不然会找出数组对象部分释放的现象,造成内存泄漏。
至于malloc,它并知道你在这块内存上要放的数组还是啥别的东西,反正它就给你一块原始的内存,在给你个内存的地址就完事。所以如果要动态分配一个数组的内存,还需要我们手动自定数组的大小:
int * ptr = (int *) malloc( sizeof(int) );//分配一个10个int元素的数组
7.new与malloc是否可以相互调用operator new /operator delete的实现可以基于malloc,而malloc的实现不可以去调用new。下面是编写operator new /operator delete 的一种简单方式,其他版本也与之类似:
void * operatornew (sieze_t size) { if(void * mem = malloc(size) return mem; else throw bad_alloc(); } voidoperatordelete(void *mem) noexcept{ free(mem); }
8.是否可以被重载opeartor new /operator delete可以被重载。标准库是定义了operator new函数和operator delete函数的8个重载版本:
//这些版本可能抛出异常 void * operatornew(size_t); void * operator new[](size_t); void * operatordelete (void * )noexcept; void * operator delete[](void *0)noexcept; //这些版本承诺不抛出异常 void * operatornew(size_t ,nothrow_t&) noexcept; void * operator new[](size_t, nothrow_t& ); void * operatordelete (void *,nothrow_t& )noexcept; void * operator delete[](void *0,nothrow_t& )noexcept;