首页 新闻 会员 周边

大家好,求帮忙解释一下这句内存分配的代码(pClientMem = (char*)((int)(pClientMem) & ~(Align-1));)

1
悬赏园豆:20 [已解决问题] 解决于 2013-02-26 10:22

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行是内存对齐的?

c++
问题补充:
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 };
小角的主页 小角 | 初学一级 | 园豆:72
提问于:2013-02-06 11:51
< >
分享
最佳答案
0

第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

收获园豆:20
jinhuawang76 | 菜鸟二级 |园豆:303 | 2013-02-09 18:59

谢谢!

小角 | 园豆:72 (初学一级) | 2013-02-26 10:22
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册