基本上我正在尝试创建一个Arena Allocator,而不使用结构,类或新操作符来手动管理内存。我有一个已定义的大小,一个字符池,一个分配方法和一个freeMemory显示方法。
请注意pool[0]
是我的索引,它会跟踪上次填充内存的位置。
const int size = 50000;
char pool[size];
void start() {
pool[0] = 1;
}
int freeMemory(void) {
int freemem = 0;
for(int i = 0; i < size; i++) {
if(pool[i] == NULL) {
freemem++;
}
}
return freemem;
}
void* allocate(int aSize)
{
if(freeMemory() == 0)
{
out();
}
else
{
char* p = NULL;
int pos = pool[0];
pool[pos] = (char) a;
p = &pool[pos];
pool[0] += a;
return((void*) &pool[pos]);
}
}
在main.cpp中:
start();
long* test1 = (long *) allocate(sizeof(long));
cout << freeMemory() << endl; //Returns 49999
*test1 = 0x8BADF00D; //Breaks here
cout << freeMemory() << endl;
当我尝试使用0x8BADF00D时,它会中断,我相信我在初始化其中一些变量时也遇到了问题。
MemoryManagerC.exe中0x000515f7处的未处理异常:0xC0000005:0x8BADF00D上的访问冲突写入位置0x00000004
答案 0 :(得分:1)
下面的代码有很多错误。
char* pointer;
for(int i = 0; i < size; i++)
{
*pointer = pool[i];
if(pointer != NULL)
{
pointer = (char*) a;
return((void*) i); //return the pointer
}
}
此行将字符复制到未知的内存位置。由于pointer
从未被初始化,我们只能猜测它指向的位置
*pointer = pool[i];
你可能想复制一个指针。
pointer = &pool[i];
虽然 意味着从pool
数组复制指针,但总是为真。该数组中的所有元素都不在地址NULL
。
if(pointer != NULL)
现在,此代码将pointer
更改为指向...更多无效地址。当a
为sizeof(long)
时,该大小将重新解释为内存地址。内存地址0x00000004
最有可能。
pointer = (char*) a;
然后在您的情况下,这将返回地址0x00000000
。因为i
是0
。
return((void*) i); //return the pointer
答案 1 :(得分:1)
分配存在一些问题:
char* pointer = NULL;
int pos = pool[0];
pool[0]
是char
。它不足以将索引存储到数组的所有成员。
pool[pos] = (char) a;
我不确定你在这里存放什么,或者为什么。您似乎将分配的大小存储在您正在分配的空间中。
pointer = &pool[pos + a];
我认为你在分配的部分之后构建一个指向内存的指针。是吗?
pool[0] += a;
在这里,您将增加显示已分配了多少池的偏移量,除了单个char
不足以支持超过一小部分分配。
return((void*) &pointer);
现在你要返回指针变量的地址。这将是堆栈上的一个地址,并且使用起来不安全。即使您只是pointer
的内容而不是其地址,我认为它会指向您刚刚在池中分配的区域。
freeMemory也存在问题。它将池(char
元素)的内容与NULL进行比较。这表明你认为它包含指针,但它们只是char
s。目前尚不清楚为什么池中未分配的部分为0.您是否允许在池中进行重新分配?
也许你可以解释一下你打算如何配置分配器?你认为它应该做什么和实际做什么之间显然存在差距,但是你认为它应该做什么并不清楚,所以提供建议很难。你如何分配数组中的空间?你允许释放吗?应该在哪里编码哪些信息?
我刚刚意识到allocate使用了未定义的变量a
。这应该与参数aSize
相同吗?这就是我在这里假设的。
答案 2 :(得分:0)
您的代码可能存在问题。
char* pointer;
for(int i = 0; i < size; i++)
{
*pointer = pool[i];
这里的问题是这可能适用于某些编译器(我认为不应该这样)。
pointer
这里没有指向分配的任何内容。所以当你这样做时
*pointer = pool[i];
pool [i]应该复制到哪里? 例如,假设我们将这样的指针声明为。
char* pointer = NULL;
现在很明显
*pointer = pool[i];
错了。
g++
(我注意到)将指针初始化为NULL。所以你的代码将是段错误的。 VC ++可能会起作用,因为它没有NULL初始化pointer
。但是你写的是一个不属于你的记忆位置。