交换两个类对象时引发的未加载wntdll.pdb报错

交换两个类对象时引发的未加载wntdll.pdb报错

    • 代码
    • 问题
    • 解决
    • 复制构造函数调用的情形
    • 疑问1
    • 疑问1解答
    • 疑问2

原标题:类模板重载赋值运算遇到的几个问题

先说错因:没有重载复制构造函数

代码

#include
#include
using namespace std;

template<typename T>
class Array {
public:
	Array(int=5);
	Array(const Array<T>&);
	~Array();
	T getsum()const;
	void show()const;//输出数组内每个元素
	T& operator[] (int);
	Array<T>& operator=(const Array<T>&);
private:
	T* a;
	int len;
};

template<typename T>
Array<T>::Array(int length)
	:len(length > 0 ? length : 5)
{
	a = new T[len];
	if (a == NULL) {//异常退出
		cout << "ERROR! Failed to allocate memory successfully!" << endl;
		exit(1);
	}
	//正常则进行初始化
	for (int i = 0; i < len; i++)
		a[i] = 0;

}
//复制构造函数
template<typename T>
Array<T>::Array(const Array<T>& arr) {
	cerr << "construction ing!";
	system("pause");
	len = arr.len;
	a = new T[len];
	if (a == NULL) {//异常退出
		cout << "ERROR! Failed to allocate memory successfully!" << endl;
		exit(1);
	}
	for (int i = 0; i < len; i++) {
		a[i] = arr.a[i];
	}
}
template<typename T>
Array<T>::~Array() {
	delete[]a;
	a = NULL;
}

template<typename T>
T Array<T>::getsum()const {
	T temp = 0;
	for (int i = 0; i < len; i++)
		temp += a[i];
	return temp;
}

template<typename T>
void Array<T>::show()const {
	for (int i = 0; i < len; i++) {
		cout << a[i] << " ";
	}
	cout << endl;
}

template<typename T>
T& Array<T>::operator[](int p) {
	if (p<0 || p>this->len - 1)
		throw invalid_argument("out of range!");
	else
		return (this->a)[p];
}



template<typename T>
Array<T>& Array<T>::operator=(const Array<T>& arr) {
	cerr << "= ing!" << endl;
	system("pause");
	if (this!=&arr){
		if (len != arr.len) {
			delete[] a;  //删掉这句程序可以正常运行
			len = arr.len;
			a = new T[len];
		}
		for (int i = 0; i < len; i++) {
			a[i] = arr.a[i];//arr[i]不行
		}
	}
	return *this;
}

template<typename T>
void swap_2(T& a, T& b) {
	T temp = b;//本句调用了复制构造函数
	b = a;//以下两句皆调用赋值运算符
	a = temp;
}


int main() {
	int n, m;
	cin >> n >> m;

	Array<int> intArray1(n);
	Array<int> intArray2(m);
	for (int i = 0; i < n; i++)
		cin >> intArray1[i];
	for (int i = 0; i < m; i++)
		cin >> intArray2[i];
	
	swap_2(intArray1, intArray2);
	intArray1.show();
	intArray2.show();
	return 0;
}



问题

提示已触发断点 未加载 wntdll.pdb
加载符号服务器无效
交换两个类对象时引发的未加载wntdll.pdb报错_第1张图片


解决

最终解决发现 在swap中 创建一个新对象时 用另一个对象初始化它
此时需要调用 复制构造函数


复制构造函数调用的情形

①当函数的参数为类的对象时
②函数的返回值是类的对象
③对象需要通过另外一个对象进行初始化

参考自:c++拷贝构造函数详解


疑问1

为什么在不加复制构造函数的情况下

Array& Array::operator=(const Array& arr) {
cerr << “= ing!” << endl;
system(“pause”);
if (this!=&arr){
if (len != arr.len) {
delete[] a;
len = arr.len;
a = new T[len];
}

删去 delete[] 可以运行(如图 未调用复制构造函数)(重载赋值中)
交换两个类对象时引发的未加载wntdll.pdb报错_第2张图片


正常运行截图
交换两个类对象时引发的未加载wntdll.pdb报错_第3张图片
2020.4.5


疑问1解答

4月6日更新:
考虑到产生上述问题的原因 可能是由于调用**默认复制构造函数** 而造成的 浅拷贝
进行如下尝试 在swap函数上加入断点 发现

void swap_2(T& a, T& b) {
T temp = b;
b = a;
a = temp;
}

在删掉重载的复制构造函数后 实际上调用的是默认复制构造函数

Array(const Array&)=delete; //删除默认拷贝构造函数
在这里插入图片描述

当进行

b=a;

交换两个类对象时引发的未加载wntdll.pdb报错_第4张图片
此时调用了重载赋值(=)运算符使得 b中的指针所指向的内存被释放
由于temp对象进行的是浅拷贝
temp对象中的指针变成了野指针

跳出swap函数后就会触发如下断点:
交换两个类对象时引发的未加载wntdll.pdb报错_第5张图片


疑问2

  • 至于为什么在结束交换时触发断点 笔者目前才疏学浅 技艺不精 暂时不能解答
    留待日后解决 恳请大佬指点

你可能感兴趣的:(笔记)