1

I made this bubble sort algorithm in C. Its working well in DM, but when executed in gcc, gives me incorrect output.

#include <stdio.h>

int i,j;

void BubbleSort(int*a, int n) //to sort the numbers
{
    int temp;
    for(i=0; i<n;i++)
        for(j=n; j>i;j--)
            if (a[j]<a[j-1])
                {
                    temp=a[j];
                    a[j]=a[j-1];
                    a[j-1]=temp;
                }
}

void Display(int * a, int n) //to display
{
    printf("\nThe sorted numbers are:\n");
    for(i=0;i<n;i++)
        {
            printf("%d, ",a[i]);
        }
}

int main()
{
    int a[50],n,choice;
    printf("\nEnter no. of elements to sort: (max. 50) ");
    scanf("%d",&n);
    printf("\nEnter the numbers : ");

    for(i=0;i<n;i++)
        scanf("%d",&a[i]);

    BubbleSort(a,n);
    Display(a,n);

    return 0;

} //End of main

Input:

5
2 1 5 3 4

DM Output:

1, 2, 3, 4, 5,

GCC Output:

1, 2, 3, 5, 4,

How and why is this happening?

Mat
  • 202,337
  • 40
  • 393
  • 406
praful
  • 55
  • 1
  • 4
  • 1
    Have you tried stepping through it in a debugger? Or printing intermediate values of variables? – Oliver Charlesworth Sep 18 '11 at 16:41
  • 2
    You're accessing the `(n+1)th` element of the array in the loop: `a[j]` is `a[5]` when `j` goes from 5 to `i`. But an array with 5 elements, does not have an index of `5`. – pmg Sep 18 '11 at 16:49
  • 1
    It is appalling to use global variables `i` and `j` under any circumstances (there are very few reasons to use a single-letter globals), and doubly so when it is just a way of avoiding declaring loop variables. C99 lets you write: `for (int i = 0; ...)` etc. – Jonathan Leffler Sep 18 '11 at 17:23
  • Oh... Thanks! that was one silly mistake... any idea why it worked on DM though?? :( – praful Sep 18 '11 at 17:25
  • 1
    It is also a poor UI that requires you to count the number of items to be sorted before you can enter them. Computers are good at counting. (You wouldn't use the Unix `sort` command if you had to tell it how many lines of data were in each file!) – Jonathan Leffler Sep 18 '11 at 17:26
  • I'm still a novice, just learning various sorting techniques... was experimenting around, trying to make a comandline tool using makefile... Guess will have to delve deeper.. make it more efficient.. :) – praful Sep 18 '11 at 17:28
  • @Jonathan: `i` and `j` are reasonable names for loop control variables. Of course I agree they shouldn't be global. Not all compilers support declarations in `for` loops; an alternative is to declare them local to the function. – Keith Thompson Sep 18 '11 at 17:40
  • 1
    @Keith: I use `i` and `j` all the time; the complaint was not about the names alone, but about using those names with global status. And I explicitly said C99; if your compiler is not C99, then it won't support the notation. (Since the question cites GCC on Ubuntu, this isn't an issue, unless you hobble it by forcing C89 modes.) I forebore to comment on 'they should be `static` so they can't be seen outside this source file'; I also forebore to comment on the unnecessarily large scope for `temp` in the sort function. – Jonathan Leffler Sep 18 '11 at 17:44
  • @Jonathan: Sure, I just wanted to make sure those points were clear to the OP; I can imagine him/her misinterpreting your advice by making the variables local *and* giving them unwieldy names. – Keith Thompson Sep 18 '11 at 18:25

1 Answers1

4

The fact that this works at all is suspect. You're overstepping the original array on this line:

if (a[j]<a[j-1])  // sketchy when j==n

You're comparing a value that you haven't initialized so the value at a[n] is whatever is there upon initialization.

This line:

for(j=n; j>i;j--)

should be:

for(j=n-1; j>i;j--)
Austin Salonen
  • 49,173
  • 15
  • 109
  • 139
  • Hey thanks!! That was a logical error...But now i'm trying to figure why it work$ed on Digital Mars compiler!! :/ – praful Sep 18 '11 at 17:26
  • 2
    @Ashwini: The behavior is undefined, so anything can happen. Working "correctly" is actually the worst outcome. – Keith Thompson Sep 18 '11 at 17:41
  • Agree about the "worst outcome" part. Had i not tested it on GCC again, i would have probably never realised the error. Now I know why people usually prefer GCC. – praful Sep 18 '11 at 17:48
  • Interesting. I understand that UB can cause anything, but I am little mystified as to how this bug could cause the described output. There will be an indeterminate value at `a[5]`, but on any system I've ever worked on it'll be *some* value. That value would either bubble into the output (if it was `<5`) or it wouldn't. I don't see how this particular bug would cause the 'sorted' array to end up as in the question, so I wonder what else is going on that I don't see. – Michael Burr Sep 18 '11 at 18:29
  • @MichaelBurr Figured anything yet?? I am still wondering why no random value is showing up... – praful Sep 21 '11 at 17:29