内存池和<无法读取内存>
Memory Pools and <Unable to read memory>
我最近将项目切换为使用我写过的线性内存分配器(用于学习)。当我初始化分配器时,我将其传递给了一个预先属于VirtualAlloc-ed的内存块。在编写分配器之前,我直接使用了此块。
在我的测试案例中,我正在使用分配器在最初的大块内存中分配播放器*的内存。为了确保每个人都在工作,我尝试像以前一样直接访问内存块,以确保根据我的期望而变化。那是我碰到内存访问错误的时候。使用VS调试器/手表窗口,我对发生的事情和何时有一个合理的想法,但是我希望在原因的问题上获得一些帮助。我将在下面布置相关的代码。
虚拟Alloc调用,后来由内存 -> TransientStorage
引用win32_State.gameMemoryBlock = VirtualAlloc(baseAddress, (size_t)win32_State.totalSize,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
分配器定义
struct LinearAllocator {
void* currentPos;
size_t totalSize;
void* startPos;
size_t usedMemory;
size_t numAllocations;
LinearAllocator();
LinearAllocator(size_t size, void* start);
LinearAllocator(LinearAllocator&) = delete;
~LinearAllocator();
void* allocate(size_t size, uint8 alignment);
void clear();
};
播放器和VEC2F定义
struct Player {
Vec2f pos;
bool32 isFiring;
real32 timeLastFiredMS;
};
union Vec2f {
struct {
real32 x, y;
};
real32 v[2];
};
相关分配器实现详细信息
void* LinearAllocator::allocate(size_t size, uint8_t alignment) {
if (size == 0 || !isPowerOfTwo(alignment)) {
return nullptr;
}
uint8_t adjustment = alignForwardAdjustment(currentPos, alignment);
if (usedMemory + adjustment + size > totalSize) {
return nullptr;
}
uint8_t* alignedAddress = (uint8*)currentPos + adjustment;
currentPos = (void*)(alignedAddress + size);
usedMemory += size + adjustment;
numAllocations++;
return (void*)alignedAddress;
}
inline uint8_t alignForwardAdjustment(void* address, uint8_t alignment) {
uint8_t adjustment = alignment - ( (size_t)address & (size_t)(alignment - 1));
if (adjustment == alignment) {
return 0; // already aligned
}
return adjustment;
}
inline int32_t isPowerOfTwo(size_t value) {
return value != 0 && (value & (value - 1)) == 0;
}
初始化代码,我尝试使用分配器
// **Can write to memory fine here**
((float*)memory->transientStorage)[0] = 4.f;
size_t simulationAllocationSize = memory->transientStorageSize / 2 / sizeof(real32);
simulationMemory = LinearAllocator(simulationAllocationSize, &memory->transientStorage + (uint8_t)0);
for (int i = 0; i < MAX_PLAYERS; i++) {
Player* p = (Player*)simulationMemory.allocate(sizeof(Player), 4);
// **also works here**
((real32*)memory->transientStorage)[0] = 3.f;
p->pos.x = 0.f; // **after this line, I got the unable to read memory error**
p->pos.y = 0.f;
p->isFiring = false;
p->timeLastFiredMS = 0.f;
// **can't write **
((real32*)memory->transientStorage)[0] = 1.f;
}
// **also can't write**
((real32*)memory->transientStorage)[0] = 2.f;
real32 test = ((real32*)memory->transientStorage)[0];
我的运行假设是我缺少明显的东西。但是,我唯一要解决的线索是,在播放器结构中设置值后,它更改了。这里的任何帮助将不胜感激!
看起来这是您的问题:
simulationMemory = LinearAllocator(simulationAllocationSize,
&memory->transientStorage + (uint8_t)0);
有一个流浪的&
操作员,导致您不是从memory->transientStorage
指向的分配内存块中分配内存,而是从memory
本身居住的任何地方。
这是将写入 p->pos.x
的原因,以覆盖 transientStorage
的值。
呼叫线性地球器的呼吁应该只是
simulationMemory = LinearAllocator(simulationAllocationSize,
memory->transientStorage + (uint8_t)0);
相关文章:
- 我无法从内存中读取值
- 如何读取特定地址的进程内存?
- 使用 OpenSSL 从内存中读取原始 SSL/TLS 证书
- 如何在 WSL 2 中读取物理内存?
- 如何使用带有矢量的 winapi 读取进程内存从另一个进程读取缓冲区?
- 从只读内存中读取结构
- 当注入程序的内存空间时,如何读取从 0 到 0xFFFFFFFFF 的每个字节?我正在创建模式扫描仪
- 如何运行外部程序,向其传递内存地址以读取/写入?
- C++指针将内存读取为 0
- 读取进程内存多级指针(DLL 注入)
- 组织从内存读取的数据的最佳方法(用于调试)c++
- 使用ClgetDeviceInfo从内存读取访问违规
- C++ - 分叉进程无法从共享内存读取
- C# 简化多指针的内存读取
- Linkedlist内存读取错误
- 从原始内存读取值(符合MISRA)
- c++ DLL内存读取崩溃
- 在wwpal rabbit中从内存读取数据
- c++中什么是预内存读取?
- 优化内存读取和写入的长期运行