memory.cpp代码(关于申请内存的,返回s_postBufferSize的开始地址,第28行不理解,求帮忙解释)
1 void* memory::alloc(size_t Size, ALIGNMENT Align, const char* FileName, int LineNumber) 2 { 3 if (!Size) 4 { 5 return 0; 6 } 7 // we store the memory size requested in 24 bits 8 debug_assert(Size < (1<<24), "allocating a block too large"); 9 10 if (Align == ALIGN_DEFAULT) 11 { 12 Align = s_defaultAlignment; 13 } 14 15 // compute the size of the total allocation 16 uint32 trueSize = Size + Align + sizeof(sMemoryBlockHeader); 17 trueSize += s_preBufferSize + s_postBufferSize; 18 19 // allocate the required memory 20 char* pRealMem = (char*)malloc(trueSize); 21 debug_assert(pRealMem, "catastrophic memory allocation error!"); 22 23 // find the aligned memory position we will give back to the caller 24 char* pClientMem = (char*) (pRealMem + Align + sizeof(sMemoryBlockHeader)); 25 pClientMem += s_preBufferSize; 26 if (Align) 27 { 28 pClientMem = (char*)((int)(pClientMem) & ~(Align-1)); 29 } 30 31 // we can now write the memory block header 32 sMemoryBlockHeader* pHeader = getMemoryBlockHeader(pClientMem); 33 pHeader->actualSize = trueSize; 34 pHeader->pointerOffset = (char*)pHeader - (char*)pRealMem; 35 36 #ifdef ENABLE_MEMORY_DEBUGGING 37 // write the prebuffer and postbuffer 38 // debug information 39 sPreBufferData* pPreBufferData = (sPreBufferData*)(pHeader+1); 40 pPreBufferData->nextHeader = s_topMemoryBlock; 41 pPreBufferData->previousHeader = 0; 42 pPreBufferData->requestedSize = Size; 43 pPreBufferData->userChecksum = 0; 44 pPreBufferData->fileLine = LineNumber; 45 46 if (s_topMemoryBlock) 47 { 48 s_topMemoryBlock->previousHeader = pPreBufferData; 49 } 50 s_topMemoryBlock = pPreBufferData; 51 52 if (FileName) 53 { 54 strncpy(pPreBufferData->fileName, FileName, MAX_MEMORY_FILENAME); // filename of the caller 55 } 56 else 57 { 58 strncpy(pPreBufferData->fileName, "unknown", MAX_MEMORY_FILENAME); // filename of the caller 59 } 60 61 uint8* prePattern = pPreBufferData->bytePattern; 62 uint8* postPattern = (uint8*)pClientMem + Size; 63 for (int i=0;i<memory::PATTERN_SIZE;i++) 64 { 65 prePattern[i]=(char)memory::PRE_PATTERN; 66 postPattern[i]=(char)memory::POST_PATTERN; 67 } 68 69 // update our memory statistics 70 s_allocCount++; 71 s_totalBytesRequested += Size; 72 s_totalBytesUsed += trueSize; 73 s_totalBytesNeeded += (trueSize-s_preBufferSize-s_postBufferSize); 74 75 s_maximumBytesRequested = 76 maximum(s_maximumBytesRequested, 77 s_totalBytesRequested); 78 79 s_maximumBytesUsed = 80 maximum(s_maximumBytesUsed, 81 s_totalBytesUsed); 82 83 s_maximumBytesNeeded = 84 maximum(s_maximumBytesNeeded, 85 s_totalBytesNeeded); 86 87 #endif 88 89 // return the client portion of the allocation 90 return (pClientMem); 91 }
第28行是内存对齐的?
ALIGNMENT 类型
1 // Data Types & Constants... 2 enum ALIGNMENT 3 { 4 ALIGN_DEFAULT= -1, 5 ALIGN_NONE = 0, 6 ALIGN_4 = 4, 7 ALIGN_8 = 8, 8 ALIGN_16 = 16, 9 ALIGN_32 = 32 10 };
第28行是为了内存地址对齐。
相关分析如下:
内存布局:
pRealMem:实际分配的内存首地址,包括5部分:
1. Align:对齐定义,其大小为Align(一般为4字节整数)、
2. sMemoryBlockHeader:内存分配头信息大小
3. s_preBufferSize:内存分配保护前缓冲(假设为ALIGNMENT的最大值)
4. ClientMem:调用者需要的内存
5. s_postBufferSize:内存分配保护后缓冲(假设为ALIGNMENT的最大值)
其中,调用者应该使用pClientMem(指向ClientMem)指针访问内存,如果没有考虑对齐,即返回ClientMem地址,如果定义了对齐,则将pClientMem按照Align定义的字节数对齐地址。
内存对齐的参考:http://hi.baidu.com/lovezl4ever/item/eec9e1202edde082af48f5aa
谢谢!