实现自己的内存池

我想预先分配一定数量的内存,并将该内存用于程序的其余部分。 该程序基本上将为一些字符串和结构分配内存。 我该如何实现? 什么数据结构用于存储指针,如何使用它来给我一个特定的数量?

例如,如果我malloc 1 MB的空间并将其放在指针p ,我该如何从中创建250 KB的片段?

这只是一个快速而肮脏的实现。

如果您希望能够将内存返回池中,则会变得更加复杂。 但是,对于快速且不那么脏的方法,您可能希望实现一些可以再次使用的代码…

 typedef struct pool { char * next; char * end; } POOL; POOL * pool_create( size_t size ) { POOL * p = (POOL*)malloc( size + sizeof(POOL) ); p->next = (char*)&p[1]; p->end = p->next + size; return p; } void pool_destroy( POOL *p ) { free(p); } size_t pool_available( POOL *p ) { return p->end - p->next; } void * pool_alloc( POOL *p, size_t size ) { if( pool_available(p) < size ) return NULL; void *mem = (void*)p->next; p->next += size; return mem; } 

根据我的经验,当使用这样的池来分配许多对象时,我想预先确定需要多少内存,这样我就不会浪费,但我也不想犯任何错误(比如不分配enoudh)。 因此,我将所有分配代码放在循环中,并设置我的池分配函数以接受在空池上执行“虚拟”分配的标志。 第二次循环,我已经计算了池的大小,所以我可以创建池并使用相同的函数调用进行实际分配,并且没有重复的代码。 您需要更改我建议的池代码,因为如果尚未分配内存,则无法使用指针算法执行此操作。

使用内存池进行内存管理 –

内存池是预分配相同大小的内存块的方法。 例如,同一类的各种对象。 因此,它更多的是设计您的软件的“内存模型”。

示例 – 动画gif具有各种帧。 假设每个帧只需要最大1024 KB。 此外,如果我们知道我们只能有两个帧,那么我们可以通过为每个帧预先分配内存来避免碎片。

[注意] – 在我们了解系统在设计时的行为的情况下,内存池更适用。 因此,内存池概念并不适用于所有地方。 // ================================================ ============================ //名称:MemoryPool.cpp //作者://版本://版权:SHREYAS JOSHI / / Description:// ============================================= ===============================

 #include  #include  struct memPool { private: char *m_poolPtr; char *m_nextAvailAddr; char *m_endAddr; public: /** Methods for the structure **/ void poolCreate(size_t size); void poolDestroy(); void * poolAlloc(size_t size); memPool():m_poolPtr(NULL),m_nextAvailAddr(NULL),m_endAddr(NULL) { std::cout<<"memPool constructor Invoked"<(gifFrame1)<(gifFrame2)<(gifFrame3)<(gifFrame3)<(gifFrame3)< 

[注意] - 为了使用ostream :: operator <<在C ++中打印char *的值,应使用static_cast(pointer_Name)将char *类型化为void *。 问题是,如果C ++编译器看到char *,那么它会查找NULL终止符 - '\ 0'。 在这种情况下,没有NULL终止符'\ 0'。 因此,您将看到未定义的行为。

内存池的优点

  1. 您可以避免内存碎片。 即使系统需要内存空间,当所需的连续块大小不可用时,malloc()也会失败。
  2. 保留空间,避免频繁的malloc()和free()。 这样可以节省时间。
  3. 当为许多子块调用malloc()时,管理/元数据与每个分配的子块相关联。 这将消耗不必要的空间。 相反,一个大块分配将避免多个管理/元数据。
  4. 如果内存空间受到限制,那么很容易调查内存泄漏。 如果池中的内存耗尽,则内存池将返回NULL。 因此,您可以轻松地隔离内存泄漏问题。