我正在编写一个类来分配内存并存储一块内存占用的字节数。它的工作原理是这样的:我们分配大小为 n + 8/4 (x64, x32) 的内存,其中 n 是所需的字节数。在这 8 个字节中,我们写入了内存块占用的字节数。移位 8 个字节,使用。
代码第 44 行出现异常:
0x6F6C6C6540,“读取访问冲突”
#include <iostream>
#include <vector>
#include <malloc.h>
using namespace std;
#ifdef _WIN64
#define SIZEBLOCK_BYTES 8
#else
#define SIZEBLOCK_BYTES 4
#endif
template<class T>
T* move_pointer_right(void* ptr, size_t bytes)
{
return reinterpret_cast<T*>(reinterpret_cast<bool*>(ptr) + bytes);
}
template<class T>
T* move_pointer_left(void* ptr, size_t bytes)
{
return reinterpret_cast<T*>(reinterpret_cast<bool*>(ptr) - bytes);
}
class BSmartheap
{
private:
vector<void*>infoheap;
public:
void* allocate_block(size_t sizeBytes);
void free_memory(void* blockMem);
size_t size_block(void* blockMem);
};
size_t BSmartheap::size_block(void* blockMem)
{
const size_t sizevec = infoheap.size();
for (size_t x = 0; x < sizevec; x++)
{
if (&infoheap[x] == blockMem)
{
return move_pointer_left<size_t>(infoheap[x], SIZEBLOCK_BYTES)[0]; // exception here
}
}
return 0;
}
void BSmartheap::free_memory(void* blockMem)
{
const size_t sizevec = infoheap.size();
for (size_t x = 0; x < sizevec; x++)
{
if (&infoheap[x] == blockMem)
{
free(move_pointer_left<void>(infoheap[x], SIZEBLOCK_BYTES));
infoheap.erase(infoheap.begin() + x);
return;
}
}
}
void* BSmartheap::allocate_block(size_t sizeBytes)
{
if (sizeBytes == 0)
{
throw exception("Size is null");
}
void* newPtr = malloc(sizeBytes + SIZEBLOCK_BYTES);
if (newPtr == nullptr)
{
throw exception("malloc return nullptr");
}
reinterpret_cast<size_t*>(newPtr)[0] = sizeBytes;
newPtr = move_pointer_right<void>(newPtr, SIZEBLOCK_BYTES);
infoheap.push_back(newPtr);
return &infoheap[infoheap.size() - 1];
}
static BSmartheap heap;
int main()
{
char* ptr = reinterpret_cast<char*>(heap.allocate_block(6));
const char* str = "Hello";
for (size_t x = 0; x < 6; x++)
{
ptr[x] = str[x];
}
cout << ptr << endl;
cout << heap.size_block(ptr) << endl;
heap.free_memory(ptr);
system("pause");
return 1;
}
为什么你返回的不是收到的地址,而是包含它的元素的地址?
代替
它会拯救你——但只能在释放内存时避免崩溃,因为你的代码中有很多这样的调用……你自己检查一下!