为什么我使用这些c ++函数获得EXC_BAD_ACCESS?

时间:2012-02-04 20:15:07

标签: c++ exc-bad-access

我正在做家庭作业,我遇到了这些问题。 当我调用allocate();

时,我得到了EXC_BAD_ACCESS
void* Pool::allocate() {
    if( free == NULL) {
        this->expandPool();
    }
    void* tmp = free;
    void* mem = malloc(elemSize);
    memcpy(&free,free,sizeof(char*)); //exec bad access right here
    memcpy(tmp,mem,sizeof(elemSize));
    return tmp;
}

这是我的expandPool方法:

void Pool::expandPool() {
    poolSize++;
    // Is this the first time?
    if(poolSize <= 1)
        pool = new char*[poolSize];
    else {
        char** tmp = new char*[poolSize];
        memcpy(tmp,pool,sizeof(pool));
        delete [] pool;
        pool = tmp;
        delete [] tmp;
    }

    char* tmp = NULL;
    char* tmp2;
    for(int i = 0; i < blockSize; i++) {
        tmp2 = new char;
        memcpy(tmp2,&tmp,sizeof(char*));
        tmp = tmp2;
    }
    pool[poolSize - 1] = tmp;
    free = tmp;
}

2 个答案:

答案 0 :(得分:2)

如果您使用Google EXC_BAD_ACCESS,您会发现这是因为您正在访问已分配内存块之外的内存。这可能有几个原因。

所以,让我们从失败点开始 - memcpy:你正在向自由指针(&free)写入free(free)的内容,并正在复制{ {1}}字节。假设free被声明为sizeof(char *),那就没问题,所以它必须是你写的char *free;的内容。

在风格上,使用这样的free来复制单个指针值 - 令人困惑。你最好用以下的东西:

memcpy

相当于你的:

free = *(char **)free;

memcpy(&free,free,sizeof(char*)); 的值在不同系统之间变化 - 在32位上为sizeof(char*),在64位上为4 - 因此分配的空间量必须至少相当大。

好的,让我们看看expandPool方法,看看free设置为:

8

在这里,您将使用tmp2 = new char; 分配一块内存块sizeof(char)。这至少需要:

1

注意:调用变量tmp2 = new char[sizeof(char *)]; 将覆盖free函数,因此您需要通过编写free来显式访问该函数。

我首先绘制一个图表,说明你想要池的内存布局以及它将如何显示/更改(a)为空时,(b)分配一个空闲的块时(c) )当您需要扩展池时分配块。使用不同的变量(::freepooltmptmp2注释图表。这将让您了解您需要做什么以及代码应该是什么样的。

充分了解数据结构和算法(通过创建图表)将有助于您正确地获取代码。

答案 1 :(得分:1)

您的代码中存在几个问题。对我来说很突出的是这一部分:

pool = tmp;
delete [] tmp;

对我来说,这会使pool指向已删除的内存。稍后在代码中使用pool会导致未定义的行为,这是语言无法解释的。代码中其他地方的失败只是预料之中。