竞技场分配器分配方法&违规写作问题

时间:2013-03-31 19:43:02

标签: visual-c++

基本上我正在尝试创建一个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

3 个答案:

答案 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更改为指向...更多无效地址。当asizeof(long)时,该大小将重新解释为内存地址。内存地址0x00000004最有可能。

        pointer = (char*) a;

然后在您的情况下,这将返回地址0x00000000。因为i0

        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。但是你写的是一个不属于你的记忆位置。