0

基本上,我正在尝试创建一个 Arena Allocator,而不使用结构、类或 new 运算符来手动管理内存。我有一个定义的大小、一个字符池、一个分配方法和一个 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

4

3 回答 3

1

There are some problems with allocate:

char* pointer = NULL;
int pos = pool[0];

pool[0] is a char. It's not big enough to store indexes to all members of the array.

pool[pos] = (char) a;

I'm not sure what you're storing here, or why. You seem to be storing the size of the allocation in the space that you're allocating.

pointer = &pool[pos + a];

I think you're constructing a pointer to the memory after the allocated portion. Is that right?

pool[0] += a;

And here you're incrementing the offset that shows how much of the pool is allocated, except that a single char isn't going to be big enough for more than a tiny quantity of allocations.

return((void*) &pointer);

And now you're returning the address of the pointer variable. That's going to be an address on the stack, and unsafe to use. Even if you just the contents of pointer instead of its address, I think it would point after the region you just allocated in your pool.

There are also problems with freeMemory. It compares the contents of the pool (char elements) with NULL. This suggests you think it contains pointers, but they are just chars. It's not clear why unallocated parts of the pool would be 0. Do you even allow deallocation within the pool?

Perhaps you could explain how you intend the allocator to work? There's obviously a gap between what you think it should do and what it actually does, but it's not clear what you think it should do, so it's hard to give advice. How do you apportion space in the array? Do you allow deallocation? What information is supposed to be encoded where?


I just realised that allocate uses the undefined variable a. Is that supposed to be the same thing as the parameter aSize? That's what I assume here.

于 2013-03-31T23:43:43.720 回答
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数组中复制一个指针,这将始终是正确的。该数组中的所有元素都不位于 address NULL

    if(pointer != NULL)

现在此代码更改pointer为指向...更多无效地址。当ais时sizeof(long),该大小被重新解释为内存地址。内存地址0x00000004最有可能。

        pointer = (char*) a;

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

        return((void*) i); //return the pointer
于 2013-03-31T20:19:28.180 回答
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 initialize pointer。但是您正在写入不属于您的内存位置。

于 2013-03-31T20:10:17.977 回答