C++:与类作为参数相关的Debug Assertion Failed报错解决

问题:

我在写一个简单的顺序表合并的函数:

serList* serList::mergeList(serList other)//归并另外一个线性表(已经排完序),返回值为另外一个线性表
{
	serList* arr2 = new serList(length + other.getLength());
	int p1 = 0;
	int p2 = 0;
	int sum = this->p + other.getP();
	while(p1 < this->p && p2 < other.getP()){
		if (arr[p1] <= other.At(p2)) {
			arr2->AddOne(arr[p1]);
			p1++;
		}
		else {
			arr2->AddOne(other.At(p2));
			p2++;
		}
	}
	sum = sum - p1 - p2;
	if (p1 == this->p) {
		for (int i = 0; i < sum; i++) {
			arr2->AddOne(other.At(p2));
			p2++;
		}
	}
	else {
		for (int i = 0; i < sum; i++) {
			arr2->AddOne(arr[p1]);
			p1++;
		}
	}
	
	return arr2;
}

main:

int main() {
	serList a;
	a.AddOne(1);
	a.AddOne(5);
	a.AddOne(5);
	a.AddOne(5);
	a.AddOne(3);
	a.AddOne(9);
	a.AddOne(9);
	a.AddOne(10);
	a.AddOne(-1);
	a.AddOne(-1);
	a.AddOne(11);
	
	serList a2;
	a2.AddOne(1);
	a2.AddOne(3);
	a2.AddOne(7);
	a2.AddOne(58);
	a2.AddOne(33);
	a2.AddOne(97);
	a2.AddOne(9);

	a.mergeList(a2)->Print();
	
	return 0;
}

然后再main函数执行的时候出现:

 代码的输出都正常,只是跳出这个窗口

解决过程:

首先这个类如下:

class serList {
private:
	int length;
	int p;
	TYPE* arr;
public:
	serList();//若不加以限定,则length默认为100
	serList(int length);//申请动态内存
	~serList();//析构函数释放申请的动态内存
	int getLength();//获取最大容量Length
	int getP();//获取当前线性表的有效元素个数
	TYPE At(int k);//获取第k个元素的值,超出错误
	bool isEmpty();//判断是否为空
	//添加x,返回添加x后的线性表本身
	serList& AddOne(TYPE x);
	//删除x,x为从头找到的第一个值为x的元素,没有就不动,返回线性表本身
	serList& Delete(TYPE x);
	void DeleteByIndex(int index);//删除下标为index的元素,没有就不动
	//删除重复元素,前提是已经排好序,返回线性表本身
	serList& DeleteRe();
	serList& Sort();//排序,采用快排,返回本身
	void Quick(int l, int r);//辅助Sort()
	void swap(TYPE* a, TYPE* b);//交换ab
	serList& Revers();//”逆置“线性表
	serList& moveL(int k);//向左循环左移k位
	serList& moveR(int k);//向右循环右移k位
	serList* mergeList(serList other);//归并另外一个线性表
	void Print();//打印serList
};

析构函数:

serList::~serList() {
	delete(arr);
}

这个类里面有个arr变量为一个指针(导致后面的问题)

此函数是对象作为参数,在c++中,类作为形参和普通变量是不一样的,类多了一个拷贝构造函数并且在函数执行结束后还会调用析构函数,而此例子中main函数中以a2作为参数,那么在调用该函数时就会产生一个临时的形参对象,该对象的初始化就是用了拷贝构造函数,会把arr的值也赋值给形参,此时a2和other(形参)有一样的arr值,有一样的地址,而在函数结束后,作为形参的other会调用析构函数,会释放arr对应的地址,这个过程也把main函数中的a2的arr对应地址释放了,a2作为一个main函数中的对象,在main函数执行结束后也会调用a2的析构函数,会释放那个已经释放的内存,就会出现开始时的那个页面。

解决方案

serList* mergeList(serList& other);//归并另外一个线性表

将参数换成引用类型,问题解决!

因为用了引用类型,函数结束时就不会调用析构函数,就不会出现释放两次的情况。

也提醒我们,以类作为函数参数时,要注意析构函数对传进对象的元素的影响,一定情况下可以用引用类型避免析构函数的调用。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值