大家好,又见面了,我是你们的朋友全栈君。
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 new(sizeof(A));//申请内存并返回指针 a = static_cast<A*>(mem); a->A::A(); //调用构造函数,但是不允许这样做,只有编译器才能主动调用构造函数 } catch(bad_alloc &memExp){ cerr<<memExp.what()<<endl; }
operator new
那么operator new中又做了什么呢
/* 这是一个最简单的重写这个函数的方法,没有处理申请不到内存的情况。 */ void* operator new(size_t sz) { return malloc(sz); } 实际上operator new的伪代码 void* operator new(std::size_t size)throw(std::bad_alloc) { using namespace std; if(size==0) //处理 0 byte申请 size=1; //视为 1 byte申请 while(true) { 尝试分配size bytes if(分配成功) return 指针(一个指向分配的内存空间的指针) //分配失败 new_hander globalHandler = set_new_handler(0)l set_new_hander(globalHandler); if(globalHandler) (*globalHandler)(); else throw std::bad_alloc();//抛出异常 } }
可以看到operator new中不断尝试申请内存
new->::operator new->malloc()
//析构函数 ~A() { printf("~A\n"); } //重载operator delete void operator delete(void *p) { printf("free\n"); free(p); } //main函数部分 ... a = new A(); a->~A(); operator delete(a); ... stdout输出 ~A free 可以通过指针主动调用析构函数,再用operator delete释放内存
placement new
有时候我们需要在已经分配的内存上构造新的对象
class A
{
public:
int a;
void* operator new(size_t sz)
{
return malloc(sz);
}
void* operator new(size_t sz,void* p) //什么都不做直接把已经申请的空间返回
return p;
};
int main()
{
void *buf = NULL;
A *a = NULL;
try
{
buf = operator new(sizeof(A)); //申请buf空间
a = new(buf)A(); //在已申请的空间buf上创建对象
/*
这样相当于a = new(buf)A();这一句只执行的构造函数,绕过了a->A::a()这样直接调用构造函数,相当于我们直接调用了构造函数
*/
}
catch(bad_alloc &memExp)
{
cerr<<memExp.what()<<endl;
}
return 0;
}
转载于:https://www.cnblogs.com/xcantaloupe/p/10582236.html
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/106917.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...