⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memblk.cpp

📁 一OCR的相关资料。.希望对研究OCR的朋友有所帮助.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        }        tprintf ("\n");      }      free (callers[callindex].counts);      callers[callindex].counts = NULL;    }  }}/********************************************************************** * MEM_ALLOCATOR::check * * Check consistency of all memory controlled by this allocator. **********************************************************************/void MEM_ALLOCATOR::check(                     //check consistency                          const char *string,  //context message                          INT8 level           //level of check                         ) {  MEMBLOCK *block;               //current block  MEMUNION *chunk;               //current chunk  MEMUNION *prevchunk;           //previous chunk  INT32 chunksize;               //size of chunk  INT32 usedcount;               //no of used chunks  INT32 usedsize;                //size of used chunks  INT32 freecount;               //no of free chunks  INT32 freesize;                //size of free chunks  INT32 biggest;                 //biggest free chunk  INT32 totusedcount;            //no of used chunks  INT32 totusedsize;             //size of used chunks  INT32 totfreecount;            //no of free chunks  INT32 totfreesize;             //size of free chunks  INT32 totbiggest;              //biggest free chunk  INT32 totblocksize;            //total size of blocks  INT32 chunkindex;              //index of chunk  INT32 blockindex;              //index of block  if (level >= MEMCHECKS)    tprintf ("\nMEM_ALLOCATOR::check:at '%s'\n", string);  totusedcount = 0;              //grand totals  totusedsize = 0;  totfreecount = 0;  totfreesize = 0;  totbiggest = 0;  totblocksize = 0;  for (blockindex = 0; blockindex < blockcount; blockindex++) {                                 //current block    block = &memblocks[blockindex];    if (level >= MEMCHECKS)      tprintf ("Block %d:0x%x-0x%x, size=%d, top=0x%x, l=%d, u=%d\n",        blockindex, block->blockstart, block->blockend,        (block->blockend - block->blockstart) * sizeof (MEMUNION),        block->topchunk, block->lowerspace, block->upperspace);    usedcount = usedsize = 0;    //zero counters    freecount = freesize = 0;    //zero counters    biggest = 0;                                 //scan all chunks    for (chunkindex = 0, prevchunk = NULL, chunk = block->blockstart; chunk != block->blockend; chunkindex++, chunk += chunksize) {      chunksize = chunk->size;   //size of chunk      if (chunksize < 0)        chunksize = -chunksize;  //absolute size      if (level >= FULLMEMCHECKS) {        tprintf ("%5d=%8d%c caller=%d, age=%d ", (int) chunkindex,          chunksize * sizeof (MEMUNION),          chunk->size < 0 ? 'U' : 'F', chunk->owner, chunk->age);        if (chunkindex % 5 == 4)          tprintf ("\n");      }                                 //illegal sizes      if (chunksize == 0 || chunk->size == -1                                 //out of bounds        || chunk + chunksize - block->blockstart <= 0 || block->blockend - (chunk + chunksize) < 0)        BADMEMCHUNKS.error ("check_mem", ABORT,          "Block=%p, Prev chunk=%p, Chunk=%p, Size=%x",          block, prevchunk, chunk,          (int) chunk->size);      else if (chunk->size < 0) {        usedcount++;             //used block        usedsize += chunksize;      }      else {        freecount++;             //free block        freesize += chunksize;        if (chunksize > biggest)          biggest = chunksize;      }      prevchunk = chunk;    }    if (level >= MEMCHECKS) {      if (level >= FULLMEMCHECKS)        tprintf ("\n");      tprintf ("%d chunks in use, total size=%d bytes\n",        (int) usedcount, usedsize * sizeof (MEMUNION));      tprintf ("%d chunks free, total size=%d bytes\n",        (int) freecount, freesize * sizeof (MEMUNION));      tprintf ("Largest free fragment=%d bytes\n",        biggest * sizeof (MEMUNION));    }    totusedcount += usedcount;   //grand totals    totusedsize += usedsize;    totfreecount += freecount;    totfreesize += freesize;    if (biggest > totbiggest)      totbiggest = biggest;    totblocksize += block->blockend - block->blockstart;  }  if (level >= MEMCHECKS) {    tprintf ("%d total blocks in use, total size=%d bytes\n",      blockcount, totblocksize * sizeof (MEMUNION));    tprintf ("%d total chunks in use, total size=%d bytes\n",      (int) totusedcount, totusedsize * sizeof (MEMUNION));    tprintf ("%d total chunks free, total size=%d bytes\n",      (int) totfreecount, totfreesize * sizeof (MEMUNION));    tprintf ("Largest free fragment=%d bytes\n",      totbiggest * sizeof (MEMUNION));  }  if (level >= MEMCHECKS)    display_counts();}/********************************************************************** * MEM_ALLOCATOR::alloc_p * * Allocate permanent space which will never be returned. * This space is allocated from the top end of a memory block to * avoid the fragmentation which would result from alternate use * of alloc_mem for permanent and temporary blocks. **********************************************************************/void *MEM_ALLOCATOR::alloc_p(              //permanent space                             INT32 count,  //block size to allocate                             void *caller  //ptr to caller                            ) {  MEMBLOCK *block;               //current block  MEMUNION *chunk;               //current chunk  if (count < 1 || count > biggestblock)                                 //request too big    MEMTOOBIG.error ("alloc_mem_p", ABORT, "%d", (int) count);  count += sizeof (MEMUNION) - 1;//round up to word  count /= sizeof (MEMUNION);  count++;                       //and add one  if (topblock == NULL) {    topblock = new_block (count);//get first block    currblock = topblock;    if (topblock == NULL) {      check_mem ("alloc_mem_p returning NULL", MEMCHECKS);      return NULL;    }  }  block = topblock;              //current block  do {    chunk = block->topchunk;    if (chunk->size < count)      block = block->next;       //try next block  }                                 //until all tried  while (chunk->size < count && block != topblock);  if (chunk->size < count) {     //still no good    chunk = (MEMUNION *) alloc ((count - 1) * sizeof (MEMUNION), caller);    //try last resort    if (chunk != NULL)      return chunk;    check_mem ("alloc_mem_p returning NULL", MEMCHECKS);    return NULL;  }  block->upperspace -= count;    //less above freechunk  if (chunk->size > count) {    chunk->size -= count;    chunk += chunk->size;  }  chunk->size = -count;          //mark as in use  if (mem_mallocdepth > 0) {    set_owner(chunk, caller);  }  else {    chunk->owner = 0;    chunk->age = 0;  }  return chunk + 1;              //created chunk}/********************************************************************** * MEM_ALLOCATOR::alloc * * Return a pointer to a buffer of count bytes aligned for any type. **********************************************************************/void *MEM_ALLOCATOR::alloc(              //get memory                           INT32 count,  //no of bytes to get                           void *caller  //ptr to caller                          ) {  MEMBLOCK *block;               //current block  MEMUNION *chunk;               //current chunk  INT32 chunksize;               //size of free chunk  MEMUNION *chunkstart;          //start of free chunk  if (count < 1 || count > biggestblock)    MEMTOOBIG.error ("alloc_mem", ABORT, "%d", (int) count);  //request too big  count += sizeof (MEMUNION) - 1;//round up to word  count /= sizeof (MEMUNION);  count++;                       //and add one  if (currblock == NULL) {                                 //get first block    currblock = new_block (count);    topblock = currblock;    if (currblock == NULL) {      check_mem ("alloc_mem returning NULL", MEMCHECKS);      return NULL;    }  }  block = currblock;             //current block  if (block->upperspace <= block->lowerspace) {                                 //restart chunklist    block->freechunk = block->blockstart;    block->upperspace += block->lowerspace;    block->lowerspace = 0;       //correct space counts  }  chunk = block->freechunk;      //current free chunk  if (chunk->size < count) {     //big enough?    do {                                 //search for free chunk      chunk = block->find_chunk (count);      if (chunk->size < count)        block = block->next;     //try next block    }                                 //until all tried    while (chunk->size < count && block != currblock);    if (chunk->size < count) {   //still no good                                 //get a new block      currblock = new_block (count);      topblock = currblock;      //set perms here too      if (currblock == NULL) {        check_mem ("alloc_mem returning NULL", MEMCHECKS);        return NULL;      }      block = currblock;      chunk = block->freechunk;  //bound to be big enough    }  }  chunkstart = chunk;            //start of chunk  if (chunk == block->topchunk && chunk + count != block->blockend)    block->topchunk += count;    //top has moved  block->upperspace -= count;    //upper part used  chunksize = chunk->size;       //size of free chunk  chunk->size = -count;          //mark as used  chunk += count;                //next free space  totalmem -= count;             //no of free elements  if (chunksize > count)         //bigger than exact?                                 //remaining space    chunk->size = chunksize - count;  else if (chunk == block->blockend) {    chunk = block->blockstart;   //restart block    block->upperspace = block->lowerspace;    block->lowerspace = 0;       //fix space counts  }  block->freechunk = chunk;      //next free block  if (mem_mallocdepth > 0) {    set_owner(chunkstart, caller);  }  else {    chunkstart->owner = 0;    chunkstart->age = 0;  }  chunkstart++;                  //start of block  return chunkstart;             //pointer to block}/********************************************************************** * MEM_ALLOCATOR::set_owner * * Set the owner and time stamp of the block and check if needed. **********************************************************************/void MEM_ALLOCATOR::set_owner(                       //get memory                              MEMUNION *chunkstart,  //chunk to set                              void *caller           //ptr to caller                             ) {  UINT16 callindex;              //hash code  callindex = hash_caller (caller);  chunkstart->owner = callindex;                                 //store evidence  chunkstart->age = malloc_serial;  malloc_minor_serial++;  if (malloc_minor_serial >= malloc_div_ratio) {    malloc_minor_serial = 0;    malloc_serial++;             //count calls    if (malloc_serial == 0) {                                 //wrap around      reduce_counts();  //fix serial numbers      malloc_serial = MAX_INT16 + 1;                                 //all worth double      malloc_div_ratio += malloc_div_ratio;    }  }  malloc_auto_count++;  if (mem_checkfreq > 0 && malloc_auto_count >= (UINT32) mem_checkfreq) {    malloc_auto_count = 0;    check_mem ("Auto check", MEMCHECKS);  }}/********************************************************************** * MEM_ALLOCATOR::dealloc * * Free a block allocated by alloc (or alloc_p). * It checks that the pointer is legal and maintains counts of the * amount of free memory above and below the current free pointer. **********************************************************************/void MEM_ALLOCATOR::dealloc(                 //free memory                            void *oldchunk,  //chunk to free                            void *caller     //ptr to caller                           ) {  MEMUNION *chunk;               //current chunk  MEMBLOCK *block;               //current block  if (oldchunk == NULL)    FREENULLPTR.error ("free_mem", ABORT, NULL);  chunk = (MEMUNION *) oldchunk;  block = currblock;             //current block  if (block == NULL)    NOTMALLOCMEM.error ("free_mem", ABORT, NULL);  do {    block = block->next;  }                                 //outside the block  while ((chunk - block->blockstart < 0 || block->blockend - chunk <= 0)    && block != currblock);  if (chunk - block->blockstart < 0 || block->blockend - chunk <= 0)                                 //in no block    NOTMALLOCMEM.error ("free_mem", ABORT, NULL);  chunk--;                       //point to size  if (chunk->size == 0)                                 //zero size    FREEILLEGALPTR.error ("free_mem", ABORT, NULL);  else if (chunk->size > 0)                                 //already free    FREEFREEDBLOCK.error ("free_mem", ABORT, NULL);  chunk->size = -chunk->size;    //mark it free  if (mem_freedepth > 0 && callers != NULL) {                                 //count calls    callers[chunk->owner].count_freeer (caller);  }  totalmem += chunk->size;       //total free memory  if (chunk - block->freechunk < 0)                                 //extra below    block->lowerspace += chunk->size;  else                                 //extra above    block->upperspace += chunk->size;}/********************************************************************** * MEM_ALLOCATOR::new_block *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -