重载==运算符触发0xC0000005访问违例错误求助
问题分析与解决方案
首先,你遇到的0xC0000005访问违例错误,核心原因是数组越界访问导致的无效指针解引用,具体出在你的循环条件上:
1. 循环条件的致命错误
你当前循环用了sizeof(cs_measure::Measure::unitStrings)作为终止条件,但sizeof返回的是整个数组的总字节数,而不是数组的元素个数。举个例子:如果你的MyString类在64位系统下占8字节(因为内部只有一个char*指针),而数组里有12个元素,那么sizeof会返回12*8=96,这意味着你的循环会从i=0一直跑到i=95——远远超出了数组实际的元素范围。
当i超过数组的真实元素个数后,unitStrings[i]访问的是数组内存之外的无效区域,这些无效的MyString对象的str成员可能是nullptr或者随机的垃圾地址。当你调用operator==时,strcmp尝试读取这个无效地址的内容,直接触发了访问违例。
修复循环条件
正确计算数组元素个数的方式是用数组总字节数除以单个元素的字节数:
const int totalUnits = sizeof(cs_measure::Measure::unitStrings) / sizeof(cs_measure::Measure::unitStrings[0]); for (int i = 0; i < totalUnits; i++) { if (cs_measure::Measure::unitStrings[i] == temp) { readMe.unit = i; // 这里额外提醒:你已经匹配到了unit,为什么还要再读一次in >> readMe.unit?可能逻辑存在冗余,建议检查 in >> readMe.unit; // 匹配到后可以直接break,避免不必要的循环 break; } }
2. 额外的安全检查建议
虽然当前崩溃的直接原因是循环越界,但为了避免后续其他场景出现类似问题,建议你检查以下几点:
- 默认构造函数的初始化:确保你的
MyString()默认构造函数不会让str成为野指针或nullptr。比如应该初始化一个空字符串:
这样即使有默认构造的MyString::MyString() { str = new char[1]; str[0] = '\0'; // 初始化为空字符串 }MyString对象,strcmp也能安全处理(因为空字符串的指针是有效的)。 const char*构造函数的空指针处理:如果传入的const char*是nullptr,也要确保构造出有效的空字符串,避免str为nullptr。- 深拷贝的正确性:确认你的拷贝构造函数和赋值运算符实现了深拷贝,避免多个
MyString对象共享同一块内存,导致析构时重复释放的问题(不过这不是当前崩溃的原因,但也是自定义字符串类的常见坑)。
内容的提问来源于stack exchange,提问作者Chris Camano
相关产品推荐
相关产品推荐

