[英]Garbage value in merge sort
While writing a simple merge sort algorithm I faced a weird problem. 在编写简单的合并排序算法时,我遇到了一个奇怪的问题。
The code is working fine until I am adding any printf() statement before return statement of mergeSort function. 直到我在mergeSort函数的return语句之前添加任何printf()语句之前,该代码才能正常工作。 If I remove that printf() statement then garbage value is coming in output. 如果删除该printf()语句,则输出中将出现垃圾值。
This is happening only when the first element of array to be sorted is largest element. 仅当要排序的数组的第一个元素为最大元素时,才会发生这种情况。
#include<stdio.h>
#include<malloc.h>
int* mergeSort(int*,int,int);
int main()
{
int arr[] = {10,2,5,6,7,0,3,1,8};
int i;
int* a = mergeSort(arr,0,8);
for(i=0;i<9;i++)
printf("%d ",a[i]);
printf("\n bye");
return 0;
}
int* mergeSort(int *arr, int left, int right)
{
int mid = (left+right)/2;
int len = right-left+1;
int* result = (int*) malloc(sizeof(int)*(len)), *arr1,*arr2;
int i=0;
int l1,l2,r1,r2;
l2 = mid+1;
i = 0;
if(len < 3)
{
if(len == 2)
{
if(arr[left] > arr[right])
{
result[0] = arr[right];
result[1] = arr[left] ;
}
else
{
result[0] = arr[left];
result[1] = arr[right];
}
return result;
}
else
{
result[0] = arr[left];
return result;
}
}
arr1 = mergeSort(arr,left,mid);
arr2 = mergeSort(arr,l2,right);
l1 = 0;
l2 = 0;
r1 = mid-left;
r2 = right-l2;
while(i<len)
{
if(l1 > r1)
{
// put rest of arr2 in result and return
while(i<len)
{
result[i] = arr2[l2];
i++;
l2++;
}
free(arr1);
free(arr2);
return result;
}
else if(l2 > r2)
{
// put rest of arr1 in result and return
while(i<len)
{
result[i] = arr1[l1];
i++;
l1++;
}
free(arr1);
free(arr2);
return result;
}
if(arr1[l1] > arr2[l2])
{
result[i] = arr2[l2];
l2++;
i++;
}
else
{
result[i] = arr1[l1];
l1++;
i++;
}
}
free(arr1);
free(arr2);
//printf("Stackoverflow"); // I have to add this to make it work
return result;
}
If I comment the third last then the code will return garbage value. 如果我在倒数第三条注释,那么代码将返回垃圾值。
Why is this problem occurring ? 为什么会出现此问题? And how can I resolve it ? 我该如何解决呢?
Here is a link to the screenshot of outputs I am getting without/with printf("Stackoverflow") statement : http://i.stack.imgur.com/OPqyd.jpg 这是我不带/带printf(“ Stackoverflow”)语句时得到的输出屏幕截图的链接: http : //i.stack.imgur.com/OPqyd.jpg
Note : It seems like it is working in other developer's system, I am using gcc 3.4.2 in mingw32. 注意:看来它正在其他开发人员的系统中工作,我在mingw32中使用gcc 3.4.2。
Answer : It seems like it it happening due to logical error in my code as Matt McNabb & Mahonri Moriancumer pointed out. 答案:好像是由于我的代码中的逻辑错误而发生的,正如Matt McNabb和Mahonri Moriancumer指出的那样。
l1 = 0;
l2 = 0;
r1 = mid-left;
r2 = right-l2;
should be: 应该:
r1 = mid-left;
r2 = right-l2;
l1 = 0;
l2 = 0;
The different behaviour seen between implementations would depend on what garbage was after you ran off the end of arr2
. 在实现之间看到的不同行为将取决于从arr2
结束运行完之后是什么垃圾。
I highly recommend that you use readable variable names (not l1
!) and comment your code to indicate what it was doing, and don't re-use variables. 我强烈建议您使用可读的变量名(而不是l1
!),并注释您的代码以指示其作用,并且不要重复使用变量。 Declare variables when needing them. 在需要变量时声明它们。 You would have spotted the problem sooner if the code had been: 如果代码是,您将早点发现问题:
int arr2_starts_at = mid + 1;
// ....
int arr1_iter = 0;
int arr2_iter = 0;
// One less than the number of items in each part
int arr1_iter_limit = mid - left;
int arr2_iter_limit = right - arr2_iter; // should be arr2_starts_at
In fact you would have put the definitions of l1
and l2
after the calculations of arr1_length
etc. so you never would have had the problem. 实际上,您应该在计算arr1_length
等之后放置l1
和l2
的定义,因此您永远不会遇到问题。
I'd also prefer using the length that you are iterating over, instead of the index you are stopping at, eg 我也希望使用您要遍历的长度,而不是您要停止的索引,例如
// no comment required, "arr1_length" says it all
int arr1_length = mid - left + 1;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.