Search code examples
arrayscarray-differencearray-initialization

Why these 2 codes don't give similar output?


The difference is in 4th line for both code(given below). In 1st one, I declared some variable and then initialized the array. In 2nd one, I initialized the array first and then declared the variables. Here's the sample output for input: 55 6.

1st code : 1       55      3       5       7       9       8       6       4       2

2nd code : 1       3       5       7       9       55      6       4       2       9

2nd one is correct btw. And in 1st code the new number is always in 2nd position.

Code 1:

#include <stdio.h>
int main()
{
    int i, num, pos, a[9] = { 1, 3, 5, 7, 9, 8, 6, 4, 2 };
    scanf("%d", &num);
    scanf("%d", &pos);
    for (i = 9; i >= pos; i--)
    {
        a[i] = a[i - 1];
    }
    a[pos - 1] = num;
    for (i = 0; i < 10; i++)
    {
        printf("%d\t", a[i]);
    }
    return 0;
}

Code 2:

#include <stdio.h>
int main()
{
    int a[9] = { 1, 3, 5, 7, 9, 8, 6, 4, 2 }, i, num, pos;
    scanf("%d", &num);
    scanf("%d", &pos);
    for (i = 9; i >= pos; i--)
    {
        a[i] = a[i - 1];
    }
    a[pos - 1] = num;
    for (i = 0; i < 10; i++)
    {
        printf("%d\t", a[i]);
    }
    return 0;
}

Solution

  • Both codes have undefined behavior in this loop:

        for (i = 9; i >= pos; i--)
        {
            a[i] = a[i - 1];
        }
    

    It is incorrect because the first iteration, assuming pos <= 9, will write to a[9] which is beyond the end of the array of length 9. The last valid index in this array is 8. There is a similar problem in the last loop where you iterate until i < 10, reading beyond the array boundary.

    The effect of undefined behavior is unpredictable: the program may behave as expected as does code #2 or produce surprising results as does code #1.

    The likely explanation in your case is the last value in the array 2 is written beyond the end of the array a, exactly in the memory location set aside by the compiler for the variable pos. So pos becomes 2 and the value 55 is inserted at the second position. This may explain what you observe, but it is only coincidental: the compiler could allocate the variables in a different order or not even in memory, so this undefined behavior could have other side effects, including a program crash. Nothing can be expected.

    Small, seemingly innocuous changes in the source causing surprising changes in the program behavior is a good indication of undefined behavior in play somewhere in the code.

    To preserve all 9 numbers and insert the new value, you should define the array with a length of 10.

    Furthermore, it is confusing to have pos be 1 based. You should perform sanitary checks on the value input and adjust pos before the loop to compare apples to apples.

    Also check the return values of scanf() to avoid undefined behavior on invalid or missing input.

    Here is a modified version:

    #include <stdio.h>
    
    int main(void)
    {
    #define LEN 10
        int a[LEN] = { 1, 3, 5, 7, 9, 8, 6, 4, 2, 0 };
        int i, num, pos;
    
        if (scanf("%d %d", &num, &pos) != 2) {
            printf("invalid input\n");
            return 1;
        }
        if (pos >= 1 && pos <= LEN) {
            pos -= 1;    // adjust pos as an index into a
            for (i = LEN; i-- > pos;) {
                a[i] = a[i - 1];
            }
            a[pos] = num;
        } else {
            // pos outside the array boundaries
            // produce an error message or do not change the array
        }
        for (i = 0; i < LEN; i++) {
            printf("%d\t", a[i]);
        }
        printf("\n");
        return 0;
    }