我只是C语言的新手。我正在使用code6.4进行C. 请参阅后面的代码。
int main(int argc, const char * argv[]) {
int a[5]={1,4,7,3,5};
merge(a, 0, 2, 4);
printf("%d",a[4]);
return 0;
}
void merge(int *a ,int p ,int q,int r){
int n1,n2;
n1=q-p+1;
n2=r-q;
int temp1[n1];
int temp2[n2];
int i,j,k;
for (i=0; i<n1; i++) {
temp1[i]=a[p+i];
}
for (i=0; i<n2; i++) {
temp2[i]=a[q+1+i];
}
j=0;
k=0;
for (i=p; i<=r; i++) {
if (temp1[j]<temp2[k]) {
a[i]=temp1[j];
j++;
}
else{
a[i]=temp2[k];
k++;
}
}
printf("%d ",a[4]);
}
所以输出是:
7 7
我上传了截屏。
但是当我评论第二个printf时:
for (i=p; i<=r; i++) {
if (temp1[j]<temp2[k]) {
a[i]=temp1[j];
j++;
}
else{
a[i]=temp2[k];
k++;
}
}
//printf("%d ",a[4]);
第一个printf的输出已更改。如下图所示。
-1231562870
我知道这可能很荒谬,但是有人可以帮助我吗?
答案 0 :(得分:2)
您的程序在此处调用未定义的行为:
if (temp1[j]<temp2[k]) { ... }
在您的具体示例中,它会在i == r
时发生,因为您将temp1[2]
与temp2[2]
进行比较,但temp2
仅包含2个元素,因此这是一个边界访问。
试图用UB推理程序是不受欢迎的;修复错误,这应该可以阻止你有其他意外。
一种可能的解决方法是将最后一个循环更改为:
for (i=p; i<=r; i++) {
if (k < n2 && j < n1) {
if (temp1[j] < temp2[k]) {
a[i] = temp1[j];
j++;
} else {
a[i] = temp2[k];
k++;
}
} else if (k < n2) {
a[i] = temp2[k];
k++;
} else {
a[i] = temp1[j];
j++;
}
}