显式调用operator new后无法访问对象成员函数的问题排查
问题根源:数组索引越界导致的非法内存访问
你遇到的EXC_BAD_ACCESS错误,核心原因是访问了超出lists数组范围的元素,导致后续调用add()时使用了无效的this指针,进而引发内存访问异常。
具体错误分析
看你的dividingMemory函数代码:
size_t memPow = getLowerLog(memorySize); auto max = (size_t) pow(2, memPow); lists[max]->add(ptr); // 这里的索引完全用错了!
你的lists数组是按照log2(内存块大小)的结果来索引的:在MyHashTable构造函数里,你循环i从0到size-1,每个lists[i]对应大小为2^i的LinkedList。但在dividingMemory里,你却用max(也就是2^memPow,实际内存块的字节数)作为索引去访问lists,这完全不符合数组的索引规则。
举个实际例子:如果memPow=3,那么max=8,但你的lists数组大小可能只有4(比如当memorySize=8时,size=getLowerLog(8)+1=3+1=4,索引范围是0-3),此时lists[8]就是访问数组边界外的内存,得到的是一个随机的无效指针。调用它的add()函数时,this指针是非法的,后续执行newNode->setNext(head)自然会触发内存访问异常。
修复方案
把lists[max]->add(ptr);改成用memPow作为索引:
lists[memPow]->add(ptr);
这样就能正确找到对应内存块大小的LinkedList实例了。
额外的优化建议
虽然不是当前崩溃的直接原因,但为了避免潜在的未定义行为,建议在Node的构造函数里初始化next指针为nullptr:
Node::Node(void * ptr):ptr(ptr), next(nullptr) { }
这样即使后续忘记调用setNext,next也不会是随机的野指针,能减少后续调试的难度。
内容的提问来源于stack exchange,提问作者Yinon
相关产品推荐
相关产品推荐

