创建一个类
cpp
class Test {
public:
Test() { std::cout << "constructor"; }
virtual ~Test() {}
void print() { std::cout << "a:" << a; }
private:
int a = 10;
};
main函数
cpp
int main(int argv, char **args)
{
std::cout << "class size:" << sizeof(Test);
void *ptr = ::malloc(sizeof(Test));
std::cout << "new class";
new (ptr) Test;
std::cout << "convert";
Test *test = (Test *)ptr;
test->print();
delete test;
::free(ptr);
return 0;
}
输出
bash
class size: 16
new class
constructor
convert
a: 10
free(): double free detected in tcache 2
Aborted (core dumped)
这里例子通过malloc
分配了 class Test
需要的内存空间
new (ptr) Test
实际上就是将ptr
内存分配给了class Test
可以看到调用了new (ptr) Test
后, 就调用了class Test
的构造函数
通过 Test *test = (Test *)ptr
将ptr
转换class Test
后
就可以调用class Test
的函数
最后可以看到当调用delete test
后再调用::free(ptr)
后
就触发了
free(): double free detected in tcache 2
Aborted (core dumped)
所以ptr
和class Test
访问的都是同一块内存
这就是内存池一个大致的原理
通过预先申请一块, 每当new的时候, 就是将预先申请的内存分配给class
delete的时候, 只是程序回收了这个内存块, 不是返还给系统
再看一个例子, 将class修改一下
bash
class Test {
public:
Test(int _A) : a(_A) { std::cout << "constructor"; }
virtual ~Test() { std::cout << "destructor, a: " << a; }
void print() { std::cout << "a:" << a; }
private:
int a;
};
main函数
cpp
int main(int argv, char **args)
{
std::cout << "class size:" << sizeof(Test);
void *ptr = ::malloc(sizeof(Test) * 10);
new (ptr) Test(10);
Test *test = (Test *)ptr;
test->print();
new ((void *)((Test *)ptr + sizeof(Test))) Test(20);
Test *test2 = ((Test *)ptr + sizeof(Test));
test2->print();
delete test;
delete test2;
::free(ptr);
return 0;
}
输出
bash
class size: 16
constructor
a: 10
constructor
a: 20
destructor, a: 10
destructor, a: 20
free(): invalid pointer
Aborted (core dumped)