内存管理02->接管三把刀为内存池做准备
其实我们做内存管理就是自己重载new。
接下来我们先看看能不能接管new,自己掌控。
1. 先接管全局new
void *MyMalloc(size_t size)
{
return malloc(size);
}
void MyDelete(void *ptr)
{
free(ptr);
}
inline void *operator new(size_t size)
{
cout << "My new()\n";
return MyMalloc(size);
}
inline void operator delete(void *ptr)
{
cout << "My delete()\n";
MyDelete(ptr);
}
void main()
{
char *ptr = new char[12];
strcpy(ptr, "hello world");
cout << ptr << endl;
delete ptr;
system("pause");
}
运行结果:

确实调用了我们自己定义的new、delete版本。但是全局影响特别大,一般不要这样做
2.在类中接管new
class foo{
public:
foo() :a(0), b(0)
{
cout << "无参数构造函数\n";
cout << "a:" << a << " b:" << b << endl;
}
foo(int x, int y)
{
cout << "有参构造函数\n";
a = x;
b = y;
cout << "a:" << a << " b:" << b << endl;
}
static void *operator new(size_t size)
{
cout << "foo::new\n";
void *ptem = malloc(size);
foo *temp = static_cast<foo *>(ptem);
return temp;
}
static void operator delete(void *p)
{
cout << "foo::delete\n";
free( p);
}
~foo()
{
cout << "~foo()\n";
}
public:
int a;
int b;
};
void main()
{
foo *f = new foo(1,2);
delete f;
system("pause");
}
运行结果:

从结果可以看出,类中接管了new,在这里解释下为什么要static,因为调用的时候并没有对象能够去调用,所以要加static。
3.接管placement new,为下一节内存池做铺垫
class foo{
public:
foo() :a(0), b(0)
{
cout << "默认构造函数\n";
}
foo(int x, int y)
{
a = x;
b = y;
cout << "有参构造函数\n"<< endl;
//throw Bad();
}
static void *operator new(size_t size)
{
cout << "foo::new\n";
void *ptem = malloc(size);
foo *temp = static_cast<foo *>(ptem);
return temp;
}
static void operator delete(void *p)
{
cout << "foo::delete\n";
free( p);
}
//模仿标准palcement new
static void *operator new(size_t size, void *exist)
{
cout << "模仿标准palcement new\n";
return exist;
}
//字符串string就是这种模式
static void *operator new(size_t size, long extra)
{
cout << "字符串模式palcement new\n";
return malloc(size + extra);
}
static void operator delete(void *p, long extra)
{
cout << "03 - delete\n";
}
~foo()
{
cout << "~foo()\n";
}
public:
int a;
int b;
};
void main()
{
foo start;
foo *p1 = new foo;
new(&start)foo();//标准
new(10)foo();//字符串模式
new(16)foo(1, 2);
system("pause");
}
运行结果:

我们可以重载placement new写出多个版本,但前提是每一个版本的声明都必须有独特的参数列,其中第一参数必须为size_t,其余参数以new所指定的placement arguments 为初值。出现在小括号内的便是所谓的placement arguments。
本文深入探讨内存管理核心,包括重载全局new与delete,类内内存管理,及placement new的多种实现方式,为构建内存池奠定坚实基础。

被折叠的 条评论
为什么被折叠?



