游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2860|回复: 7

求解释pClientMem = (char*)((int)(pClientMem) & ~(Align-1)); 的作用

[复制链接]

1

主题

8

帖子

23

积分

注册会员

Rank: 2

积分
23
发表于 2013-2-6 14:24:48 | 显示全部楼层 |阅读模式
本帖最后由 yiluoff 于 2013-2-6 14:26 编辑

这是一个memory.cpp代码,关于申请内存的,返回s_postBufferSize的开始地址,第20行代码不理解是干什么的,求大大们帮忙解释一下。

代码如下:

  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"); if (Align == ALIGN_DEFAULT)
  9. {
  10.   Align = s_defaultAlignment;
  11. } // compute the size of the total allocation
  12. uint32 trueSize = Size + Align + sizeof(sMemoryBlockHeader);
  13. trueSize += s_preBufferSize + s_postBufferSize; // allocate the required memory
  14. char* pRealMem = (char*)malloc(trueSize);
  15. debug_assert(pRealMem, "catastrophic memory allocation error!"); // find the aligned memory position we will give back to the caller
  16. char* pClientMem = (char*) (pRealMem + Align + sizeof(sMemoryBlockHeader));
  17. pClientMem += s_preBufferSize;
  18. if (Align)
  19. {
  20.   pClientMem = (char*)((int)(pClientMem) & ~(Align-1));
  21. } // we can now write the memory block header
  22. sMemoryBlockHeader* pHeader = getMemoryBlockHeader(pClientMem);
  23. pHeader->actualSize = trueSize;
  24. pHeader->pointerOffset = (char*)pHeader - (char*)pRealMem;#ifdef ENABLE_MEMORY_DEBUGGING
  25. // write the prebuffer and postbuffer
  26. // debug information
  27. sPreBufferData* pPreBufferData = (sPreBufferData*)(pHeader+1);
  28. pPreBufferData->nextHeader = s_topMemoryBlock;
  29. pPreBufferData->previousHeader = 0;
  30. pPreBufferData->requestedSize = Size;
  31. pPreBufferData->userChecksum = 0;
  32. pPreBufferData->fileLine = LineNumber; if (s_topMemoryBlock)
  33. {
  34.   s_topMemoryBlock->previousHeader = pPreBufferData;
  35. }
  36. s_topMemoryBlock = pPreBufferData; if (FileName)
  37. {
  38.   strncpy(pPreBufferData->fileName, FileName, MAX_MEMORY_FILENAME); // filename of the caller
  39. }
  40. else
  41. {
  42.   strncpy(pPreBufferData->fileName, "unknown", MAX_MEMORY_FILENAME); // filename of the caller
  43. } uint8* prePattern = pPreBufferData->bytePattern;
  44. uint8* postPattern = (uint8*)pClientMem + Size;
  45. for (int i=0;i<memory::PATTERN_SIZE;i++)
  46. {
  47.   prePattern[i]=(char)memory::PRE_PATTERN;
  48.   postPattern[i]=(char)memory::POST_PATTERN;
  49. } // update our memory statistics
  50. s_allocCount++;
  51. s_totalBytesRequested += Size;
  52. s_totalBytesUsed += trueSize;
  53. s_totalBytesNeeded += (trueSize-s_preBufferSize-s_postBufferSize);

  54. s_maximumBytesRequested =  maximum(s_maximumBytesRequested,s_totalBytesRequested); s_maximumBytesUsed = maximum(s_maximumBytesUsed,s_totalBytesUsed); s_maximumBytesNeeded = maximum(s_maximumBytesNeeded,s_totalBytesNeeded);#endif  // return the client portion of the allocation
  55. return (pClientMem);
  56. }
复制代码

第28行是内存对齐的?希望大大们给小弟讲解下。
     下面是ALIGNMENT枚举


  1. enum ALIGNMENT
  2. {
  3.   ALIGN_DEFAULT= -1,
  4.   ALIGN_NONE = 0,
  5.   ALIGN_4  = 4,
  6.   ALIGN_8  = 8,
  7.   ALIGN_16 = 16,
  8.   ALIGN_32 = 32
  9. };
复制代码

代码调用方法

  1. _nextOpenList = (uint16*)alloc_aligned_memory(sizeof(uint16)*m_maxCount, memory::ALIGN_32);//new(memory::ALIGN_32) int16[m_maxCount];
复制代码


这些代码是摘自《地形引擎》那本书的。


0

主题

769

帖子

1052

积分

金牌会员

Rank: 6Rank: 6

积分
1052
发表于 2013-2-10 19:42:50 | 显示全部楼层
那块是预留做内存块头
块头存储着 块的大小 用于对付 删除块的时候 不需要从外部传入块的大小
因为delete[]传入的参数中的大小是不能用的

1

主题

8

帖子

23

积分

注册会员

Rank: 2

积分
23
 楼主| 发表于 2013-2-26 10:20:57 | 显示全部楼层
无名剑 发表于 2013-2-10 19:42
那块是预留做内存块头
块头存储着 块的大小 用于对付 删除块的时候 不需要从外部传入块的大小
因为delete[ ...

虽然不是我想要的问题,还是谢谢您的答案。

1

主题

8

帖子

23

积分

注册会员

Rank: 2

积分
23
 楼主| 发表于 2013-2-26 10:25:08 | 显示全部楼层
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

1

主题

8

帖子

23

积分

注册会员

Rank: 2

积分
23
 楼主| 发表于 2013-2-26 10:25:54 | 显示全部楼层
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

1

主题

8

帖子

23

积分

注册会员

Rank: 2

积分
23
 楼主| 发表于 2013-2-26 10:26:53 | 显示全部楼层
pRealMem:实际分配的内存首地址,包括5部分:

1. Align:对齐定义,其大小为Align(一般为4字节整数)、

2. sMemoryBlockHeader:内存分配头信息大小

3. s_preBufferSize:内存分配保护前缓冲(假设为ALIGNMENT的最大值)

4. ClientMem:调用者需要的内存

5. s_postBufferSize:内存分配保护后缓冲(假设为ALIGNMENT的最大值)



其中,调用者应该使用pClientMem(指向ClientMem)指针访问内存,如果没有考虑对齐,即返回ClientMem地址,如果定义了对齐,则将pClientMem按照Align定义的字节数对齐地址。

1

主题

8

帖子

23

积分

注册会员

Rank: 2

积分
23
 楼主| 发表于 2013-2-26 10:27:22 | 显示全部楼层

1

主题

8

帖子

23

积分

注册会员

Rank: 2

积分
23
 楼主| 发表于 2013-2-26 10:28:06 | 显示全部楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-27 02:48

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表