内存池基本思路:
在程序启动时预先分配一大块内存(通过malloc或new),随后将整块内存分割成多个较小内存块,按需分配给不同的对象使用,并提供回收内存块机制,以供再次使用。
简易内存池代码:
#include <iostream>
#include <vector>
#include <memory>
class MemoryPool {
public:
MemoryPool(size_t bolck_size, size_t block_count)
: block_size_(bolck_size), block_count_(block_count) {
pool_ = new char[block_size_ * block_count_];
for (size_t i = 0; i < block_count_; i++) {
free_blocks_.push_back(pool_ + i * block_size_); //将第i个内存块的首地址存入向量
}
}
MemoryPool() {
delete[] pool_;
}
//分配内存块
void* allocate() {
if (free_blocks_.empty()) {
return nullptr;
}
void* block = free_blocks_.back(); //取出内存块
free_blocks_.pop_back();
return block;
}
//释放(回收)内存块
void deallocate(void* block) {
free_blocks_.push_back(block);
}
private:
size_t block_size_; //内存块大小
size_t block_count_; //内存块数量
char* pool_; //内存池
std::vector<void *> free_blocks_; //void* 类型
};
为什么用 size_t ?
定义:size_t 是由标准库定义的类型, 是 C++ 中用于表示对象大小和数组索引的 无符号整数类型。常用于表示内存的大小或容器的大小等。
优点:
1、避免溢出:其为无符号类型,确保了内存或数组大小的值不会出现负数。
2、平台无关性:size_t 是根据系统架构定义的,能够适应不同平台上的字节数,保证代码的可移植性。
测试代码:
class MyClass {
public:
void print() {
std::cout << "初始化成功!";
}
};
int main()
{
MemoryPool pool(sizeof(MyClass), 10);
MyClass* obj1 = static_cast<MyClass*>(pool.allocate()); //获取内存,并将 void* 转为 MyClass* 类型
new(obj1) MyClass(); //定位new
obj1->print();
return 0;
}
定位new
目的:在已分配的内存空间中调用构造函数来构造对象
用法:new (memory) Type(args);
// 在 memory(指针) 指向的地址处构造 Type 类型的对象,args为构造函数参数列表
十分简易的内存池代码,先大致理解内存池,后续逐步优化更新笔记...