malloc、calloc、realloc、alloca
- malloc:申请指定字节数的内存。申请到的内存中的初始值不确定
- calloc:为指定长度的对象,分配能容纳其指定个数的内存。申请到的内存的每一位(bit)都初始化为0
- realloc:更改以前分配的内存长度(增加或减少)。当增加长度时,可能需将以前分配区的内容移动到另一个足够大的区域,而新增区域内的初始值则不确定。
- alloca:在栈上申请内存。程序在出栈的时候,会自动释放内存。但是需要注意的是,alloca不具可移植性,而且在没有传统堆栈的机器上很难实现。alloca不宜使用在必须广泛移植的程序中。C99中支持变长数组(VLA),可以用来代替alloca。
malloc、free
用于分配、释放内存
malloc、free使用
申请内存,确认是否申请成功
char *str = (char*) malloc(100); assert(str != nullptr);
释放内存后指针置空
free(p); p = nullptr;
new、delete
- new/new[]:完成两件事,先底层调用malloc分配了内存,然后调用构造函数(创建对象)。
- delete/delete[]:也完成两件事,先调用析构函数(清理资源),然后底层调用free释放空间
- new在申请内存时会自动计算所需字节数,而malloc则需要我们自己输入申请内存空间的字节数
new、delete使用
申请内存,确认是否申请成功
int main() { T* t = new T(); // 先内存分配 ,再构造函数 delete t; // 先析构函数,再内存释放 return 0; }
定位new
定位new(placement new)允许我们向new传递额外的地址参数,从而在预先指定的内存区域创建对象。
new (place_address) type new (place_address) type (initializers) new (place_address) type [size] new (place_address) type [size] { braced initializer list }
place_address
是个指针initializers
提供一个(可能为空的)以逗号分隔的初始值列表
delete this合法吗
合法,但:
- 必须保证this对象是通过new(不是new[]、不是placement new、不是栈上、不是全局、不是其他对象成员)分配的
- 必须保证调用delete this的成员函数是最后一个调用this 的成员函数
- 必须保证成员函数delete this后面没有调用this了
- 必须保证delete this后没有人使用了
如何定义一个只能在堆上(栈上)生成对象的类
只能在堆上
方法:将析构函数设置为私有
原因:C++是静态绑定语言,编译器管理栈上对象的生命周期,编译器在为类对象分配空间时,会先检查类的析构函数的访问性。若析构函数不可访问,则不能在栈上创建对象。
只能在栈上
方法:将new和delete重载为私有
原因:在堆上生成对象,使用new关键词操作,其过程分为两个阶段:第一阶段,使用new在堆上寻找可用内存,分配给对象;第二阶段,调用构造函数生成对象。将new操作设置为私有,那么第一阶段就无法完成,就不能在堆上生成对象。
评论