我正在做家庭作业,我遇到了这些问题。 当我调用allocate();
时,我得到了EXC_BAD_ACCESSvoid* 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;
}
答案 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) )当您需要扩展池时分配块。使用不同的变量(::free
,pool
,tmp
和tmp2
注释图表。这将让您了解您需要做什么以及代码应该是什么样的。
充分了解数据结构和算法(通过创建图表)将有助于您正确地获取代码。
答案 1 :(得分:1)
您的代码中存在几个问题。对我来说很突出的是这一部分:
pool = tmp;
delete [] tmp;
对我来说,这会使pool
指向已删除的内存。稍后在代码中使用pool
会导致未定义的行为,这是语言无法解释的。代码中其他地方的失败只是预料之中。