【发布时间】:2019-07-10 18:28:46
【问题描述】:
我的程序中的第二次递归传递了一个奇怪的数组,然后整个过程被破坏了。 我传递了一个数组及其大小,然后将其分为两个数组 left_arr 和 right_arr。我们对左数组继续上述过程,直到它达到基本条件。有一个类似的问题,程序传递高、低值并在同一个数组上进行更改。 我想知道为什么我的代码会突然输出。忽略征服功能,因为在接近它之前发生错误,我无法检查。
我尝试通过打印原始数组、左右数组来调试我的代码,但找不到错误。
好的,我的第一个疑问是程序每次都创建一个新数组,即按值传递?
以及,如何调试此类问题?
#include<bits/stdc++.h>
using namespace std;
int conquer(int left_arr[],int right_arr[], int arr[]){
int i=0,j=0,k=0;
int length_left = sizeof(left_arr)/sizeof(left_arr[0]);
int length_right = sizeof(right_arr)/sizeof(right_arr[0]);
//int l = length_left +
length_right;
while(i<length_left && j<length_right)
{
if(left_arr[i]<=right_arr[j])
{
arr[k++] = left_arr[i++];
}
else
{
arr[k++] = right_arr[j++];
}
}
while(i<length_left)
{
arr[k++] = left_arr[i++];
}
while(j<length_right)
{
arr[k++] = right_arr[j++];
}
for(int i=0; i<l;i++)
cout<<arr[i]<<" ";
cout<<endl;
return 0;
}
int divide(int *arr,int n)
{
if(n<2)
return 0;
int mid=n/2;
int x = n-mid;
cout<<" n ="<<n<<" mid ="<<mid<<endl;
int left_arr[mid];
int right_arr[n-mid]; //for debug
cout<<"arr:";
for(int m=0;m<n;m++)
cout<<arr[m]<<" ";
cout<<endl;
for(int i=0;i<mid;i++)
left_arr[i]=arr[i]; //for debug
cout<<"Larr:";
for(int k=0;k<mid;k++)
cout<<left_arr[k]<<" ";
cout<<endl;
for(int j=mid;j<n;j++)
right_arr[j] = arr[j];
cout<<"Rarr:"; //for debug
for(int j=mid;j<n;j++)
cout<<right_arr[j]<<" ";
cout<<endl<<endl;
divide(left_arr,mid);
divide(right_arr,x);
//conquer(left_arr,right_arr,arr);
return 0;
}
int main()
{
int n,arr[]={2,5,4,6,1,8,3};
divide(arr,7);
for(int i=0;i<7;i++)
{
cout<<arr[i]<<" ";
}
return 0;
}
n =7 中 =3 错误:2 5 4 6 1 8 3 拉尔:2 5 4 拉尔:6 1 8 3
n =3 中 =1 错误:2 5 4 拉尔:2 拉尔:5 4
n =2 中 =1 arr:7536080 5 拉尔:7536080 Rarr:5 //来自这里的错误
n =4 中 =2 arr:-1 0 4200483 6 拉尔:-1 0 Rarr:4200483 6
n =2 中间 =1 错误:-1 0 拉尔:-1 拉尔:0
n =2 中间 =1 arr:7536080 5 拉尔:7536080 拉尔:5
【问题讨论】:
-
int left_arr[mid];不是标准 C++,除非mid是一个常量表达式。这可能是也可能不是问题的一部分,但您不应该使用非标准语言扩展。 -
int length_left = sizeof(left_arr)/sizeof(left_arr[0])是一个错误。至少是标准的c++。sizeof(left_arr)是指针的大小而不是数组的大小。 -
@OP 您知道,如果您使用
std::vector及其工具(例如at()调用来确定边界访问问题。即使是提到的sizeof错误也可以通过使用size()来防止。这就是 VLA 语法对您的健康有害的原因。它隐藏了错误,如果条目数量非常多(堆栈溢出),它会导致错误。 -
#include<bits/stdc++.h>loads the gun。using namespace std;takes the safety off。真的要小心。