简体   繁体   中英

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.

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. 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 -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      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:

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).

You could let short circuiting help you by changing your while loop's condition to this:

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.

Same happens in your next while loop. So change it to this:

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

Last, but not least, the condition of the last while loop:

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

will also invoke Undefined Behavior, since j will be equal to 5, and k equal to 8.

Changing it to:

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

will prevent Undefined Behavior from being invoked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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