📄 suballoc.c
字号:
currDiff = curr->allocSize - size; if(currDiff == 0) { /* this is as good as it gets */ bestfit = curr; break; } if(currDiff < bestfitDiff) { bestfitDiff = currDiff; bestfit = curr; } curr = curr->next;#endif }#if !SUBALLOC_FIRSTFIT if(bestfit != NULL) { RemoveElement(pool, bestfit);#if SUBALLOC_DEBLOG DebugMsg("suballoc: best fit found block of %u bytes for alloc of %u bytes\n", bestfit->allocSize, size);#endif return bestfit; }#endif /* nothing was found */ return NULL;}BOOL RemovePoolElementByAddr(SUBALLOC_POOL *pool, SUBALLOC_HEADER *header){ SUBALLOC_HEADER *curr; assert(pool != NULL); assert(IsHeaderOkay(header) == TRUE); curr = pool->head; while(curr != NULL) { assert(IsHeaderOkay(curr) == TRUE); if(curr == header) { RemoveElement(pool, curr); return TRUE; } curr = curr->next; } return FALSE;}void RemoveLargestPoolElement(SUBALLOC_POOL *pool){ SUBALLOC_HEADER *curr; SUBALLOC_HEADER *largest; assert(pool != NULL); largest = NULL; /* walk the list, looking for the largest allocated block */ for(curr = pool->head; curr != NULL; curr = curr->next) { assert(IsHeaderOkay(curr) == TRUE); if(largest == NULL) { largest = curr; continue; } if(curr->allocSize > largest->allocSize) { largest = curr; continue; } } /* if one was found, remove it */ if(largest != NULL) {#if SUBALLOC_DEBLOG DebugMsg("removing largest buffer of %u bytes from pool of %u bytes\n", largest->allocSize, pool->totalMemorySize);#endif if(largest->prev != NULL) { largest->prev->next = largest->next; } if(largest->next != NULL) { largest->next->prev = largest->prev; } /* removed, so destroy it and account for it in the pool */ assert(pool->totalMemorySize >= largest->allocSize); pool->totalMemorySize -= largest->allocSize; FreePoolElement(largest); }}/*// public functions*/void InitializeMemory(void){ InitializePool(&freePool); InitializePool(&reservedPool);}void TerminateMemory(void){ SUBALLOC_HEADER *header; if(reservedPool.head != NULL) {#if SUBALLOC_DEBLOG DebugMsg("UNFREED MEMORY: %u bytes held in reserved pool\n", reservedPool.totalMemorySize);#endif#if SUBALLOC_WARNING printf("suballoc: %u bytes unfreed\n", reservedPool.totalMemorySize);#endif }#if SUBALLOC_DEBLOG DebugMsg("suballoc: %u bytes held in free pool\n", freePool.totalMemorySize);#endif while((header = RemoveFirstElement(&reservedPool)) != NULL) { assert(IsHeaderOkay(header) == TRUE); assert(IsEndSignatureOkay(header) == TRUE);#if SUBALLOC_DEBLOG DebugMsg("Removing reserved alloc for %u bytes from %s line %u\n", header->userSize, header->file, header->line);#endif FreePoolElement(header); } while((header = RemoveFirstElement(&freePool)) != NULL) { assert(IsHeaderOkay(header) == TRUE); /* dont check end signature, it is not valid in free pool */#if SUBALLOC_DEBLOG DebugMsg("Removing free alloc for %u bytes from %s line %u\n", header->userSize, header->file, header->line);#endif FreePoolElement(header); }}void *_AllocMemory(uint size, const char *file, uint line){ SUBALLOC_HEADER *header;#if SUBALLOC_DEBLOG DebugMsg("Allocating %u bytes in file %s line %u\n", size, file, line);#endif#if DEBUG totalAllocations++;#endif if(size == 0) {#if SUBALLOC_DEBLOG DebugMsg("Allocation for 0 bytes in file %s line %u\n", file, line);#endif return NULL; } /* if buffer of sufficient size already in pool, use that one */ if((header = RemovePoolElementBySize(&freePool, size)) == NULL) { /* need to create a new pool item */ if((header = CreatePoolElement(size)) == NULL) { /* out of memory! */#if SUBALLOC_DEBLOG DebugMsg("System heap out of memory! file %s line %u\n", file, line);#endif return NULL; } } else {#if DEBUG freePoolHits++;#endif } assert(IsHeaderOkay(header) == TRUE); /* replace the headers file and line with this new information */ if(file != NULL) { StringCopy(header->file, file, SUBALLOC_MAX_HEADER_FILE_SIZE); } else { header->file[0] = NUL; } header->line = line; header->userSize = size; /* set the end signature */ SetEndSignature(header); /* add the new suballoc to the reserved pool */ AddPoolElement(&reservedPool, header); assert(IsHeaderOkay(header) == TRUE); assert(IsEndSignatureOkay(header) == TRUE); return GetUserBuffer(header);}void _FreeMemory(void *ptr, const char *file, uint line){ SUBALLOC_HEADER *header;#if !SUBALLOC_DEBLOG UNREF_PARAM(file); UNREF_PARAM(line);#endif if(ptr == NULL) {#if SUBALLOC_DEBLOG DebugMsg("Tried to free NULL pointer in file %s line %u\n", file, line);#endif return; } header = (SUBALLOC_HEADER *) (((BYTE *) ptr) - sizeof(SUBALLOC_HEADER)); assert(IsHeaderOkay(header) == TRUE); assert(IsEndSignatureOkay(header) == TRUE);#if SUBALLOC_DEBLOG DebugMsg("Freeing %u bytes (%u alloced) in file %s line %u\n", header->userSize, header->allocSize, file, line);#endif if(RemovePoolElementByAddr(&reservedPool, header) == FALSE) { /* doh! */ HtpMsg(MSG_ERROR, NULL, "Fatal error: block of memory freed not in reserved pool, exiting ...\n"); exit(1); }#if SUBALLOC_CLEARMEM memset(GetUserBuffer(header), SUBALLOC_FREE_BYTE, header->allocSize);#endif /* move it back into the free pool */ AddPoolElement(&freePool, header);#if SUBALLOC_MAXFREEPOOLSIZE /* check to see that the free pool size hasnt grown too big */ while(freePool.totalMemorySize > SUBALLOC_MAXFREEPOOLSIZE) { RemoveLargestPoolElement(&freePool); }#endif}void *_ResizeMemory(void *ptr, uint newSize, const char *file, uint line){ SUBALLOC_HEADER *header; SUBALLOC_HEADER *newHeader;#if SUBALLOC_DEBLOG DebugMsg("Reallocing to new size of %u bytes in file %s line %u\n", newSize, file, line);#endif if((newSize == 0) && (ptr != NULL)) { /* treat as a free */ FreeMemory(ptr); return NULL; } if((ptr == NULL) && (newSize != 0)) { /* treat as an alloc */ return AllocMemory(newSize); } if((ptr == NULL) && (newSize == 0)) { /* treat as a dumbo programmer */ return NULL; } header = PointerToHeader(ptr); assert(IsHeaderOkay(header) == TRUE); assert(IsEndSignatureOkay(header) == TRUE); if(RemovePoolElementByAddr(&reservedPool, header) == FALSE) { /* oof */ HtpMsg(MSG_ERROR, NULL, "Fatal error: block of memory freed not in reserved pool, exiting ...\n"); exit(1); } /* resize memory buffer */ newHeader = ResizePoolElement(header, newSize); if(newHeader == NULL) { /* failed to resize */ AddPoolElement(&reservedPool, header); return NULL; } /* succeeded, fill in rest of header */ if(file != NULL) { StringCopy(newHeader->file, file, SUBALLOC_MAX_HEADER_FILE_SIZE); } else { newHeader->file[0] = NUL; } newHeader->line = line; /* add to reserve pool and return to user */ AddPoolElement(&reservedPool, newHeader); assert(IsHeaderOkay(newHeader) == TRUE); assert(IsEndSignatureOkay(newHeader) == TRUE); return GetUserBuffer(newHeader);}uint MemorySize(void *ptr){ SUBALLOC_HEADER *header; if(ptr == NULL) { return 0; } header = PointerToHeader(ptr); assert(IsHeaderOkay(header) == TRUE); if(IsHeaderOkay(header) == FALSE) { return 0; } return header->userSize;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -