C++重载+运算符实现myfunnyarray数组拼接输出垃圾值问题
重载运算符出现垃圾值的问题定位与修复
核心错误点
- 动态数组长度记录缺失,错误使用
sizeof计算数组长度
类成员int *x是指向动态内存的指针,sizeof(x)在32位环境下固定为4、64位环境下固定为8,仅代表指针本身占用的字节数,和实际分配的int数组元素个数没有任何关系。原代码里重载+、重载<<的所有长度计算逻辑全用了sizeof(x),导致创建拼接数组时长度计算完全错误,后续循环按错误长度读写内存,直接拿到野指针指向的垃圾值。 - 违反C++三/五法则,浅拷贝导致未定义行为
类自定义了析构函数用delete[]释放动态数组,但没有实现拷贝构造函数、拷贝赋值运算符。原代码中operator+的形参、operator<<的形参都是按值传递,会触发默认生成的浅拷贝逻辑:直接把原对象的x指针值复制给形参对象,多个对象指向同一块堆内存。当形参对象析构时,会释放这块公共内存,原对象的x指针就变成悬空指针,后续读取必然得到垃圾值,还可能触发二次释放的崩溃。 - main函数存在语法笔误
代码里的cout<<saim<<endl;、cout<<paim<<endl;属于未定义的标识符,是输入时的遗漏,实际应该是输出对象s、p的内容。 - 拼接逻辑的长度匹配错误
原代码创建结果数组时,传入构造函数的长度是sizeof(x)+sizeof(obj.x),也就是两个指针的大小之和,远小于实际需要拼接的数组总长度,导致后续拷贝时越界写内存。
修复后的可运行代码
#include <iostream> using namespace std; class myfunnyarray{ int *x; int len; // 新增成员,记录动态数组的实际长度 public: myfunnyarray(int size){ len = size; x = new int[size]; for(int i=0;i<size;i++) x[i]=0; } myfunnyarray(int size, int value){ len = size; x = new int[size]; for(int i=0;i<size;i++) x[i]=value; } // 实现拷贝构造,解决浅拷贝问题 myfunnyarray(const myfunnyarray& other) { len = other.len; x = new int[len]; for(int i=0; i<len; i++) { x[i] = other.x[i]; } } // 实现拷贝赋值运算符,解决浅拷贝问题 myfunnyarray& operator=(const myfunnyarray& other) { if(this == &other) return *this; delete[] x; len = other.len; x = new int[len]; for(int i=0; i<len; i++) { x[i] = other.x[i]; } return *this; } ~myfunnyarray(){ delete [] x; } // 形参改为const引用,避免不必要的拷贝 myfunnyarray operator+(const myfunnyarray& obj) const { int total_len = len + obj.len; myfunnyarray result(total_len); // 拷贝第一个操作数的内容 for (int i = 0; i < len; i++) { result.x[i] = x[i]; } // 拷贝第二个操作数的内容 for (int i = 0; i < obj.len; i++) { result.x[len + i] = obj.x[i]; } return result; } friend ostream &operator<< (ostream &out, const myfunnyarray& o); }; // 形参改为const引用,避免不必要的拷贝 ostream &operator<< (ostream &out, const myfunnyarray& o){ for (int i = 0; i < o.len; i++) { out << o.x[i]; if (i < o.len - 1) { out << ","; } } return out; } int main(){ myfunnyarray s(5); cout << s << endl; myfunnyarray p(5,10); cout << p << endl; myfunnyarray q = s + p; cout << q; }
内容的提问来源于stack exchange,提问作者Muhammad Saim Iqbal
相关产品推荐
相关产品推荐

