2

This is a program on sorting integers.

#include <stdio.h>

int main(void) {
    int n, i, j, k;
    int nmbr[100];

    printf("\n How many numbers ? ");
    scanf("%d", &n);

    printf("\n");
    for (i = 0; i < n; ++i) {
        printf(" Number %d : ", i + 1);
        scanf("%d", &nmbr[i]);
    }

    for (i = 0; i < n; ++i) {
        for (j = 0; j < n; ++j) {
            if (nmbr[j] > nmbr[j + 1]) {
                k = nmbr[j];
                nmbr[j] = nmbr[j + 1];
                nmbr[j + 1] = k;
            }
        }
    }

    printf("\n Numbers after sorting : \n");
    for (i = 0; i < n; ++i) {
         printf (" %d", nmbr[i]);
    }

    return 0;
}

It works fine, but when I enter some number that contains more than 2 digits, the first number that is printed is negative and really big. I don't also get the last integer too. I enter N as 4, then the numbers I entered were 25, 762, 588, and 34. The result I get is:

-1217260830 25 34 588

What seems to be the problem?

lmiguelvargasf
  • 63,191
  • 45
  • 217
  • 228
Anik Shahriar
  • 151
  • 1
  • 11
  • 3
    The value is a garbage value that you have swapped into the array by accessing `nmbr[j + 1]` when `j == n - 1`, which is one beyond the legal bounds of (the initialised part of) the array. – M Oehm Dec 05 '16 at 11:39
  • Possible duplicate of [How dangerous is it to access an array out of bounds?](http://stackoverflow.com/questions/15646973/how-dangerous-is-it-to-access-an-array-out-of-bounds) – dandan78 Dec 05 '16 at 11:48

4 Answers4

3

You are running the loop as for (j = 0; j < n; ++j) which means j will have values from 0 to n-1 which are valid array indices (or array elements with relevant values).

But, inside that loop you are accessing an element beyond the last. For instance, in

if (nmbr[j] > nmbr[j + 1])

you are accessing nmbr[j + 1]. If the current value of j in n-1, then you are accessing nmbr[n-1 + 1] i.e. nmbr[n] which will be a value outside the array and may contain a garbage value (which might as well be negative!).

If you are trying something like Bubblesort, you might want to run the inner loop like for (j = 0; j < n - 1; ++j).

skrtbhtngr
  • 2,223
  • 23
  • 29
3

There are multiple problems in your code:

  • You do not check the return values of scanf(). If any of these input operations fail, the destination values remain uninitialized, invoking undefined behavior and potentially producing garbage output.

  • You do not verify that the number of values provided by the user is at most 100. The reading loop will cause a buffer overflow if n is too large.

  • Your sorting logic is flawed: in the nested loop, you refer to nmbr[j + 1] which is beyond the values read from the user. This invokes undefined behavior: potentially causing a garbage value to appear in the output.

Here is a corrected version:

#include <stdio.h>

int main(void) {
    int n, i, j, k;
    int nmbr[100];

    printf("\n How many numbers ? ");
    if (scanf("%d", &n) != 1 || n > 100) {
        printf("input error\n");
        return 1;
    }

    printf("\n");
    for (i = 0; i < n; ++i) {
        printf(" Number %d : ", i + 1);
        if (scanf("%d", &nmbr[i]) != 1) {{
            printf("input error\n");
            return 1;
        }
    }

    for (i = 0; i < n; ++i) {
        for (j = 0; j < n - 1; ++j) {
            if (nmbr[j] > nmbr[j + 1]) {
                k = nmbr[j];
                nmbr[j] = nmbr[j + 1];
                nmbr[j + 1] = k;
            }
        }
    }

    printf("\n Numbers after sorting :\n");
    for (i = 0; i < n; ++i) {
         printf (" %d", nmbr[i]);
    }
    printf("\n");

    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • As your answer, if n != 1 or n > 100, error will occur. Okay, but it seems that if I enter 20 which is not equals to one, it will show error. – Anik Shahriar Dec 05 '16 at 11:59
  • @AnikShahriar: I'm afraid you misread the test: I compare the return value of `scanf()` to `1`, checking that **1** conversion succeeded, and then verify that `n <= 100`. – chqrlie Dec 05 '16 at 12:01
2

Your Sorting Logic is wrong. It should be:

for (i = 0; i < n; ++i){

        for (j = 0; j < (n-1); ++j){

            if (nmbr[j] > nmbr[j + 1]){

                k = nmbr[j];
                nmbr[j] = nmbr[j + 1];
                nmbr[j + 1] = k;

            }

        }

You are trying to access out of bounds of array, when you iterate in your second loop using j. This is causing the garbage value.

As per your example involving 4 elements, when you try to access j+1, it will try to access nmbr[3+1] in the last iteration of second loop which leads to out of bounds access.

Jay
  • 24,173
  • 25
  • 93
  • 141
0

Problem is with the sorting logic as suggested by fellow coders. But It is always good coding habit to initialize the variables. Also use the qualifier if are dealing with positive numbers only.

unsigned int n = 0 , i = 0, j = 0, k = 0;
unsigned int nmbr[100] = {0};

If you would have initialized them, out put of your program would be following, which might help you tracing the problem by yourself.

0 25 34 588

MGpro
  • 33
  • 4