c++ 内存管理(一)
分配 | 释放 | 所属 | 可否重载 |
---|---|---|---|
malloc | free) | C函数 | 不可 |
new | delete | C++表达式 | 可 |
::operator new) | ::operator delete) | c++函数 | 可 |
allocator::allocate) | allocator::deallocate) | c++标准库 | 自由搭配任何容器 |
new
A *a = new A);
上面代码我们申请了一个A类的对象使用new。
new里面的步骤
1.申请空间
2.调用A类的构造函数
3.返回指针
/** new中大概是这样调用的 */ A* a=NULL; try{ void* mem = operator newsizeofA));//申请内存并返回指针 a = static_cast<A*>mem); a->A::A); //调用构造函数,但是不允许这样做,只有编译器才能主动调用构造函数 } catchbad_alloc &memExp){ cerr<<memExp.what)<<endl; }
operator new
那么operator new中又做了什么呢
/* 这是一个最简单的重写这个函数的方法,没有处理申请不到内存的情况。 */ void* operator newsize_t sz) { return mallocsz); } 实际上operator new的伪代码 void* operator newstd::size_t size)throwstd::bad_alloc) { using namespace std; ifsize==0) //处理 0 byte申请 size=1; //视为 1 byte申请 whiletrue) { 尝试分配size bytes if分配成功) return 指针(一个指向分配的内存空间的指针) //分配失败 new_hander globalHandler = set_new_handler0)l set_new_handerglobalHandler); ifglobalHandler) *globalHandler)); else throw std::bad_alloc);//抛出异常 } }
可以看到operator new中不断尝试申请内存
new->::operator new->malloc)
//析构函数 ~A) { printf"~A\n"); } //重载operator delete void operator deletevoid *p) { printf"free\n"); freep); } //main函数部分 ... a = new A); a->~A); operator deletea); ... stdout输出 ~A free 可以通过指针主动调用析构函数,再用operator delete释放内存
placement new
有时候我们需要在已经分配的内存上构造新的对象
class A
{
public:
int a;
void* operator newsize_t sz)
{
return mallocsz);
}
void* operator newsize_t sz,void* p) //什么都不做直接把已经申请的空间返回
return p;
};
int main)
{
void *buf = NULL;
A *a = NULL;
try
{
buf = operator newsizeofA)); //申请buf空间
a = newbuf)A); //在已申请的空间buf上创建对象
/*
这样相当于a = newbuf)A);这一句只执行的构造函数,绕过了a->A::a)这样直接调用构造函数,相当于我们直接调用了构造函数
*/
}
catchbad_alloc &memExp)
{
cerr<<memExp.what)<<endl;
}
return 0;
}
转载于:https://www.cnblogs.com/xcantaloupe/p/10582236.html