简体   繁体   English

为什么我的C代码每次都不起作用?

[英]Why does my C code not work everytime?

I wrote this code to merge two sorted arrays. 我编写了这段代码以合并两个排序的数组。 The desired output is: 所需的输出是:

Merged array:0 1 2 3 4 5 6 7 8 9 10 11 12

I am using gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 to compile my code. 我正在使用gcc(Ubuntu 5.4.0-6ubuntu1〜16.04.4)5.4.0 20160609编译我的代码。

The problem is that sometimes I get the desired output when I execute the a.out file but on other occasions, the cursor keeps blinking and no result is shown. 问题是,有时我在执行a.out文件时会得到所需的输出,但是在其他情况下,光标会一直闪烁并且没有结果显示。 Why is this happening? 为什么会这样呢? Is there something wrong with my code? 我的代码有问题吗?

#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");

}

You have undefined behaviour (accessing the array out of bounds). 您有未定义的行为(超出范围访问数组)。 Use gcc -fsanitize=undefined to create an executable that can detect all sorts of bad behaviour. 使用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

The lines 20, 25 and 30 are 第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]){

Is there something wrong with my code? 我的代码有问题吗?

Yes! 是!

It gets out of bounds when accessing a , here for example: 访问时,它得到出界的a ,例如,在这里:

while(a[j] < b[k] && j<m ){
    array[index] = a[j];
    ++index;
    ++j;
}

j will eventually get the value 4, enter the body of the if statement, and when it tries to resolve the condition of the while loop, it will access a[5] , which is out of bounds, thus causing Undefined Behavior (which explains why your code runs sometimes, and others hang). j最终将获得值4,输入if语句的主体,当它尝试解决while循环的条件时,它将访问a[5] ,该值超出范围,从而导致未定义行为 (这说明了为什么您的代码有时会运行,而其他人会挂起)。

You could let short circuiting help you by changing your while loop's condition to this: 您可以通过将while循环的条件更改为此来让短路对您有所帮助:

while(j < m && a[j] < b[k]) {

which when j reaches m m, resulting in j<m evaluated to false, will not go through a[j] < b[k] , because a logical and operation will be false, if at least one of its operands are false. j达到m m时,导致j<m评估为false,则不会通过a[j] < b[k]运算,因为如果至少一个操作数为false,则逻辑和运算将为false。

Same happens in your next while loop. 在您的下一个while循环中也会发生同样的情况。 So change it to this: 因此,将其更改为:

while(k < n && a[j] > b[k]) {

Last, but not least, the condition of the last while loop: 最后但并非最不重要的是last while循环的条件:

while(a[j] == b[k]){

will also invoke Undefined Behavior, since j will be equal to 5, and k equal to 8. 也会调用未定义行为,因为j等于5, k等于8。

Changing it to: 更改为:

while(j < m && k < n && a[j] == b[k]) {

will prevent Undefined Behavior from being invoked. 将防止调用未定义行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM