丁香婷婷色五月激情综合深爱

发布日期:2022-06-18 17:04    点击次数:63

C说话动态内存分派

 序论

领先要判辨为何需要动态内存分派,闇练C说话的读者应该对这个比拟闇练,需要一段内存时会使用malloc函数来央求所需要大小的内存,函数复返一段内存的首地址。粗陋来说,动态内存分派的平允在于需要内存的时辰不错按需分派,当不需要内存的时辰不错将其开释掉,这么不错高效的诓骗内存。底下本文从零运转达成一个完美的动态内存分派。

粗陋动态内存分派达成

内存分派是将莫得使用的内存块给需要的变量(粗鄙变量、指针变量、结构体变量等等)使用,由于其使用后需要进行开释,这就会导致满足的内存是散布在内存池中的。因此,必须要对内存进行治理,也即是对内存的使用情况做瑰丽。

上图是一个内存池使用后的某一时间,不错看到,使用的块和莫得使用的块并不是聚合的,这么就需要用一个表对其进行瑰丽,这个表称为BitMap。假定当今将内存按照每个Byte进行永诀,然后用一个bit对块进行瑰丽,1暗示已使用,0暗示莫得使用,这么一个块需要一个bit。

底下来用C说话来达成这个粗陋的动态内存分派。 

#include <stdio.h>  #define MEM_POOL_SIZE  64  unsigned char MemPool[MEM_POOL_SIZE];  unsigned char BitMap[MEM_POOL_SIZE/8]={0};  //BitMap[0] MSB->LSB  MemPool[0 ~ 8]  //BitMap[1] MSB->LSB  MemPool[9 ~15]  //BitMap[2] MSB->LSB  MemPool[16~23]  // ...  void InitMemAlloc(void)  {      int i=MEM_POOL_SIZE;      while(i--)      {          MemPool[i]=0;      }      i=MEM_POOL_SIZE/8;      while(i--)      {          BitMap[i]=0;      }  }  void *MemAlloc(unsigned int m_size)  {      unsigned int i=0,j=0,k=0,index=0,
国模丰满少妇私拍count=0,mapv=0,cache;      if(m_size>MEM_POOL_SIZE)      {          return NULL;      }      else      {          for(;i<MEM_POOL_SIZE/8;i++)          {              mapv=BitMap[i];   //取出高位              for(j=0;j<8;j++)              {                  cache=(mapv&0x80);                  if(cache==0)                  {                      count++;                      if(count==m_size)                     {                          for(;k<m_size;k++)                          {                              BitMap[(index+k)/8]|=(1<<(7-((index+k)%8)));                          }                          return &MemPool[index];                      }                  }                  else                  {                      count=0;                      iindex=i*8+j+1;                  }                  mapv<<=1;              }          }          return NULL;      }  }   void MemFree(void *p,unsigned int m_size)  {      unsigned int k=0,index=(((unsigned int)p)-(unsigned int)MemPool);      for(;k<m_size;k++)      {          BitMap[(index+k)/8]&=~(1<<(7-((index+k)%8)));      }  }  void MemPrintBitMap(void)  {      unsigned int i,j,value;        for(i=0;i<MEM_POOL_SIZE/8;i++)      {          value=BitMap[i];          for(j=0;j<8;j++)          {              if(value&0x80)                  printf("1 ");              else                  printf("0 ");              value<<=1;          }          printf("\n");      }  }  double MemGetUsedPercent(void)  {      unsigned int i,j,value;      double ret=0.0;      for(i=0;i<MEM_POOL_SIZE/8;i++)      {          value=BitMap[i];          for(j=0;j<8;j++)          {              if(value&0x80)                  ret++;              value<<=1;          }      }      return (ret*100)/MEM_POOL_SIZE; }  int main(int argc, char **argv)  {      int *p=MemAlloc(10);      printf("The pool is used=%f\n",丁香婷婷色五月激情综合深爱MemGetUsedPercent());      MemPrintBitMap();      int *q=MemAlloc(5);      printf("The pool is used=%f\n",MemGetUsedPercent());      MemPrintBitMap();     MemFree(p,5);      printf("The pool is used=%f\n",MemGetUsedPercent());      MemPrintBitMap();      return 0;  } 

最终终局输出成果如下:

上头仍是达成了一个粗陋的动态内存分派,不错完成内存的分派和开释以及输出使用率和检察位图。这种容颜达成的动态内存分派不会产生里面碎屑,这亦然其上风场合,但其错误很明显即是诓骗率太低。

实用的动态内存分派

扎眼的读者可能仍是发现上头的粗陋动态内存分派有一个错误,即是一个bit只可暗示一个字节,也即是说暗示8个字节就需要一个字节的位图,这种映射导致其内存的

这关于很厚情况是比拟销耗的。为了晋升诓骗率,就必须将映射块的粒度增大,也即是一个Bit的映射限度对应多个字节。

上图给出了一个bit映射到64Byte,这么:

诚然诓骗率变高了,然则其会产生里面碎屑,所谓里面碎屑即是在最小粒度内无法使用的内存空间,为何这个空间无法使用了,原因在于当在央求内存块的时辰,其内存只不错64B对齐的,即使小于64B,也得按64B来看作,因为这个粒度仍是被bitmap瑰丽使用了,当下次使用时,其无法被分派。因此,不错看到,粒度越大,其可能产生的里面内存碎屑越大,内存诓骗率和碎屑是需要量度了,好的算法只可处置外部碎屑问题,无法处置里面碎屑问题,因此在达成动态内存分派时必须量度接头,以达到最优成果。 

 





Powered by 东北女人毛多水多牲交视频 @2013-2022 RSS地图 HTML地图