new和delete
在动态内存中为对象分配空间,并返回指向该空间的指针
当执行一条new表达式时如:int *p=new int(1024),实际执行了三步操作
- 调用名为operator new(operator new[])的标准库函数 ,该函数分配一块足够大的、原始的、未命名的内存空间以便存储特定类型的对象(或对象数组)
- 编译器运行相应的构造函数构造这些对象并传入其值
- 返回指向该对象的指针
当调用一条delete表达式时如:delete p,实际上执行了两步操作
- 调用p指向对象的析构函数
- 调用operator delete的标准库函数释放空间
可以重载控制内存分配的函数operator new和operator delete,编译器会用重载的版本替换默认的版本
void* operator new(size_t size) {
if (void* mem = malloc(size)) {
cout << "alloc successfully" << endl;
return mem;
}
else
throw bad_alloc();
}
void operator delete(void* mem) noexcept {
cout << "delete" << endl;
free(mem);
}
定位new:new (place_address)type(initializers) place_address必须是一个指针
定位new允许我们在一个分配好的、特定的内存地址上构造对象,显示调用析构函数销毁对象,但不会释放内存
malloc和free
malloc和free函数是C++从C语言继承来的,定义在头文件cstdlib中,malloc接受一个表示待分配字节数的size_t,返回指向分配空间的指针或返回0表示失败,free接受一个void*,将内存返还给系统
malloc和new的区别
- new 返回指定类型的指针,并且可以自动计算所需要大小
- malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针,int* p = (int *) malloc (sizeof(int)*128)
- malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的
- new灵活上的局限性:分配和构造组合在一起
- new是运算符,malloc是C的库函数
allocator
标准库allocator类定义在memory中,allocator是模板类,allocator对象负责内存的分配,构造,析构,回收
- allocate函数分配一段原始得到,未构造的内存
- construct函数来构造对象
- destory函数使对象调用析构函数销毁对象
- deallocate函数释房内存
note:为了使用allocate分配的内存,我们必须使用construct构造对象,否则行为是未定义的
note:我们只能对真正构造了的对象执行destory
智能指针
头文件memory中
- shared_ptr 允许多个指针共享一个对象
- unique_ptr 独占一个对象
- weak_ptr shared_ptr的伴随类
最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数,此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr