我刚刚在读Game Engine Architecture by Jason Gregory S.212,当我偶然发现他分配对齐内存的代码时。我认为他正在产生内存损坏,我自己用以下代码进行了尝试:
void* myalloc( unsigned size )
{
// this will not return a valid memory address but its ok since
// it will never be dereferenced! its just to check what if a real malloc would
// return this obviously UNALIGNED memory address
return reinterpret_cast<void*>( 0x00001 );
}
void* allocatedAligned( unsigned size_bytes, unsigned alignment )
{
unsigned expandedSize_bytes = size_bytes + alignment;
unsigned rawAddress = (unsigned)myalloc( expandedSize_bytes );
unsigned mask = alignment - 1;
unsigned misalignment = rawAddress & mask;
unsigned adjustment = alignment - misalignment;
unsigned alignedAddress = rawAddress + adjustment;
unsigned* ptrAdjustment = reinterpret_cast<unsigned*>( alignedAddress - 4 );
//*ptrAdjustment = adjustment; //Corruption here
//return reinterpret_cast<unsigned*>( alignedAddress ); this is what jasons function normally returns
return ptrAdjustment;
}
int main()
{
void* ptr = allocatedAligned( 4, 4 );
std::cout << ptr << std::endl; // this shouldn't print an address lower than 0x0001
return 1;
}
对齐工作正常,但我必须反对行*ptrAdjustment = adjustment
,因为恕我直言,它会损坏内存。它在从 myalloc() 收到的地址之前写入内存,还是我错了?
main()
不应打印任何小于 myalloc() 返回的地址的地址?!
期待您的答复,谢谢!
注意:这个例子是关于:内存将被写入哪里,而不是关于:myalloc()
返回错误的内存....
(我对代码的更改:
- 使用无符号代替
U32
- 使用
myalloc()
而不是allocateUnaligned()
- c++ 转换而不是 c 风格 )
最佳答案
代码已损坏。如果 malloc 返回已经正确对齐的地址(例如 0)并且您请求 8 字节对齐的地址,则代码将返回地址 4,这显然是错误的。应删除以下行:
unsigned* ptrAdjustment = reinterpret_cast<unsigned*>( alignedAddress - 4 );
代码应该只返回alignedAddress:
return reinterpret_cast<unsigned*>( alignedAddress );
(也应该是 void*
而不是 unsigned*
并且他应该使用 size_t
而不是 unsigned
)。如果您希望代码在已正确对齐的情况下返回原始 malloc() 地址,您只需将上面的行更改为:
return reinterpret_cast<void*>(misalignment?alignedAddress:rawAddress);
同样迂腐的是,函数中应该有断言来验证对齐是 2 的幂,例如assert((alignment&(alignment-1))==0);
关于c++ - 对齐的内存分配器: memory corruption (game engine architecture[Jason Gregory]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24476294/