因为疏忽了vector的size()返回值类型而引起的bug——c++

在实现归并排序的非递归方式,遇到了一个bug。事故现场如下:

//传入三个点,因为待归并的两个有序数组长度可能不同
void merge_un(vector<int>&vec, vector<int>&ans,
	int left_start, int right_start, int right_end) {
	int left_end = right_start - 1;
	int len = right_end - left_start;
	int index = left_start;

	while (left_start <= left_end && right_start <= right_end) {
		ans[index++] = vec[left_start] <= vec[right_start] ?
			vec[left_start++] : vec[right_start++];
	}

	while (left_start <= left_end) ans[index++] = vec[left_start++];
	while (right_start <= right_end) ans[index++] = vec[right_start++];

	while (len--)
		vec[right_end--] = ans[right_end];
}

//两两归并相邻有序子列
void merge_pass(vector<int>&vec, vector<int>&ans, int len) {
	int i, j;
	//int lenn = ans.size();
	//每次循环,i=i+2*len,因为归并的两段总长度为2*len
	//每次都跳过归并好的那一段,然后去寻找下一个两段进行归并
	//i<ans.size()-2*len,保证了前面成对的都处理完
	//对于尾巴,要另外处理。尾巴可能是两块不一样长的,也可能只有一块
	for (i = 0; i <= (ans.size() - 2 * len); i += 2 * len) {
		if (len == 8)
			int a = 0;
		merge_un(vec, ans, i, i + len, i + 2 * len - 1);
	}
	//说明尾巴有两块,一块长度为len,另一块长度为vec.size()-i-len
	if (i + len < vec.size())
		merge_un(vec, ans, i, i + len, vec.size() - 1);
	else //说明尾巴只有一块,那么直接拷贝即可
		for (j = i; j < vec.size(); j++) ans[j] = vec[j];
}

//自底向上,非递归实现
void merge_sort_un(vector<int>vec) {
	vector<int>ans(vec.size());
	int len = 1;

	while (len < vec.size()) {
		merge_pass(vec, ans, len);
		len *= 2;
		merge_pass(ans, vec, len);
		len *= 2;
	}
	for (auto i : vec)
		cout << i << " ";
	cout << endl;
}

看起来干干净净的小绵羊,居然在运行的时候报错了!

 

认真分析了半天,并没有任何边界的问题,但是为什么会发生指针越界呢?于是乎我开始抓bug,终于发现,bug发生的情况是:

当len=8,ans.size()=9时,居然能在断点处——int a=0; 停住了!!!所以是因为这里引起的指针越界的(越界情况发生在merge_un函数中)

//两两归并相邻有序子列
void merge_pass(vector<int>&vec, vector<int>&ans, int len) {

	。。。

	for (i = 0; i <= (ans.size() - 2 * len); i += 2 * len) {
		if (len == 8)
			int a = 0;
		merge_un(vec, ans, i, i + len, i + 2 * len - 1);
	}
	
    。。。
}

百思不得其解。9-2*8=-7才对啊,怎么会执行到这一步呢?怪自己稀松了,忽视了vector的size()返回值是unsigned int !!!

哭了,这种低级错误以后不要再犯了。谨记。

 

 

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值