C++遍历指针数组调用typeid时触发0xC0000005访问冲突错误
崩溃根因定位
核心问题点
- 循环边界计算完全错误:代码中用
i < sizeof(ptr)作为循环终止条件,实际获取的是指针本身的内存大小(64位编译环境下为8字节、32位环境下为4字节),并非你申请的100个指针的数组总长度,导致循环遍历的范围和实际有效赋值的元素完全不匹配 - 数组存在大量未初始化的野指针:通过
new Electronic_device*[100]申请的是指针类型的数组,C++默认不会对内置类型数组做零初始化,你仅手动给ptr[0]/ptr[1]/ptr[2]三个位置赋了有效对象地址,剩余位置的指针都是未初始化的垃圾值。你看到的崩溃地址0xCDCDCDCD正是Visual Studio Debug模式下,未初始化堆内存的固定填充标记值。
崩溃触发逻辑
当循环执行到索引i≥3的位置时,ptr[i]存储的是无效的野指针值,代码中直接执行typeid(*ptr[i])会对这个无效地址做解引用操作,直接触发内存访问违规异常。
为什么单独运行typeid(*ptr[0]).name()可以正常工作?因为ptr[0]是你明确赋值的、指向有效栈对象的指针,不存在无效解引用的问题。
修复方案
- 修正循环边界:将错误的循环终止条件替换为实际的有效元素数量。如果仅遍历你已经赋值的3个设备,直接写
i < 3即可;如果要遍历整个申请的数组,需要单独定义常量记录数组长度(如const int DEVICE_ARRAY_SIZE = 100),循环条件写为i < DEVICE_ARRAY_SIZE,不要再用sizeof计算数组长度。 - 初始化数组的所有元素为安全值:申请堆数组时补充零初始化语法,写法为
Electronic_device** ptr = new Electronic_device*[100]{};,此时所有未手动赋值的指针会被统一初始化为空指针nullptr,从根源上避免野指针问题。 - 增加空指针防护:在循环做类型判断前,先跳过空指针元素,示例代码:
for (i = 0; i < 实际有效遍历长度; i++) { if (ptr[i] == nullptr) continue; // 跳过空元素,避免无效解引用 if (typeid(*ptr[i]) == typeid(Cellphone)) { cout << "Cellphone" << endl; } // 其余类型判断逻辑保持不变 }
内容的提问来源于stack exchange,提问作者Michael Younes
相关产品推荐
相关产品推荐

