我写了这段代码来合并两个排序的数组。所需的输出是:
Merged array:0 1 2 3 4 5 6 7 8 9 10 11 12
我正在使用gcc(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609来编译我的代码。
问题在于,当我执行a.out文件时,有时会得到所需的输出,但在其他情况下,光标会一直闪烁并且没有显示结果。为什么会这样?我的代码有问题吗?
#include<stdio.h>
#include<stdlib.h>
int main(void){
//change arrays as per your need but it should be sorted
int a[] = {1,2,3,7,8};
int b[] = {0,3,5,6,9,10,11,12};
int m =sizeof(a) / sizeof(int);
int n =sizeof(b) / sizeof(int);
int index=0, j=0, k=0;
int size = m + n;
int array[size];
while(index < size) {
while(a[j] < b[k] && j<m ){
array[index] = a[j];
++index;
++j;
}
while(a[j] > b[k] && k<n){
array[index] = b[k];
++index;
++k;
}
while(a[j] == b[k]){
array[index] = a[j];
j++; index++;
}
}
printf("Merged array: ");
for(int i=0; i<size; i++)
printf("%d ", array[i]);
printf("\n");
}
答案 0 :(得分:6)
您有未定义的行为(访问数组越界)。使用gcc -fsanitize=undefined
创建可以检测各种不良行为的可执行文件。
% gcc -g fffff.c -Wall -Wextra -fsanitize=undefined
% ./a.out
fffff.c:20:12: runtime error: index 5 out of bounds for type 'int [5]'
fffff.c:20:12: runtime error: load of address 0x7ffd0c0c9804 with insufficient space for an object of type 'int'
0x7ffd0c0c9804: note: pointer points here
08 00 00 00 04 00 00 00 04 00 00 00 04 00 00 00 00 00 00 00 03 00 00 00 05 00 00 00 06 00 00 00
^
fffff.c:25:12: runtime error: index 5 out of bounds for type 'int [5]'
fffff.c:25:12: runtime error: load of address 0x7ffd0c0c9804 with insufficient space for an object of type 'int'
0x7ffd0c0c9804: note: pointer points here
08 00 00 00 04 00 00 00 04 00 00 00 04 00 00 00 00 00 00 00 03 00 00 00 05 00 00 00 06 00 00 00
^
fffff.c:30:12: runtime T: index 5 out of bounds for type 'int [5]'
fffff.c:30:12: runtime error: load of address 0x7ffd0c0c9804 with insufficient space for an object of type 'int'
0x7ffd0c0c9804: note: pointer points here
08 00 00 00 04 00 00 00
第20,25和30行是
20 while(a[j] < b[k] && j<m ){
25 while(a[j] > b[k] && k<n){
30 while(a[j] == b[k]){
答案 1 :(得分:5)
我的代码有问题吗?
是!
访问a
时会超出范围,例如:
while(a[j] < b[k] && j<m ){
array[index] = a[j];
++index;
++j;
}
j
最终将得到值4,输入if语句的主体,当它尝试解析while循环的条件时,它将访问a[5]
,这是超出界限的,从而导致未定义的行为(这解释了为什么你的代码有时会运行,而其他代码会挂起)。
你可以让短路帮助你改变你的while循环条件:
while(j < m && a[j] < b[k]) {
当j
到达m
m时,导致j<m
评估为false,将不会通过a[j] < b[k]
,因为逻辑和操作将为false,如果在至少有一个操作数是假的。
在你的下一个while循环中也是如此。所以改成它:
while(k < n && a[j] > b[k]) {
最后但并非最不重要的是,最后一个while循环的条件:
while(a[j] == b[k]){
也会调用未定义的行为,因为j
将等于5,k
等于8。
将其更改为:
while(j < m && k < n && a[j] == b[k]) {
将阻止调用未定义的行为。