Home > OS >  Bubble sort is working correctly but sometimes it aborts. If I change the size of the array it doesn
Bubble sort is working correctly but sometimes it aborts. If I change the size of the array it doesn

Time:09-17

Should I be using a long for the array or a float? Should I be making the array size larger?

When I use a larger array, say for instance 12 numbers, the program does not abort but instead prints a minus figure as the first item when its been sorted.

I know this is a memory issue but I'm just not entirely sure how to fix it.

Some explanation would be great!

PS. I am new to C. I don't remember encountering any issues like this with python.

#include <stdio.h>

void print_grades();
void average();
void swap();
void bubble_swap();

int main()
{
    const int SIZE = 10;
    int grades[SIZE] = { 67, 56, 65, 76, 32, 14, 59, 34, 6, 77 };
    
    print_grades(grades, SIZE);
    average(grades, SIZE);
    bubble_swap(grades, SIZE);

    return 0;
}

// This function prints the array  
void print_grades(int grades[], int size)
{
    int i;
    printf("My grades are:\n");

    for (i = 0; i < size; i  )
    {
        printf("%i\t", grades[i]);
    }
}

// This function calculates the average of the array
void average(int grades[], int size)
{
    int i;
    double sum = 0.0, average;
    printf("\nMy average grade is: ");
    for (i = 0; i < size; i  )
    {
        sum  = grades[i];
    }
    printf("%.1f\n", sum/size);
}

// This function swaps two ints 
void swap(int *a, int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

// This is the bubble sort function.
void bubble_swap(int grades[], int size)
{
    int i, j;
    for (i = 0; i < size; i  )
        for (j = 0; j < size; j  )
        {
            if (grades[j] < grades[j 1])
            {
                NULL;
            }
            else
            {
                swap(&grades[j], &grades[j 1]);
            }
        }
    printf("\nMy sorted grades are:\n");
    for (i = 0; i < size; i  )
    {
        printf("%i\t", grades[i]);
    }
}

CodePudding user response:

There are multiple problems in your code:

  • The inner loop runs one time too many: to avoid accessing an element beyond the end of the grades arrat, instead of for (j = 0; j < size; j ) you should run:

      for (j = 0; j < size - 1; j  )
    
  • Also note that the function prototypes should include the argument lists.

  • an array with a variable size cannot be initialized in C.

Here is a modified version:

#include <stdio.h>

void print_grades(const int grades[], int size);
void average(const int grades[], int size);
void swap(int *a, int *b);
void bubble_swap(int grades[], int size);

int main() {
    int grades[] = { 67, 56, 65, 76, 32, 14, 59, 34, 6, 77 };
    const int SIZE = sizeof(grades) / sizeof(grades[0]);

    print_grades(grades, SIZE);
    average(grades, SIZE);
    bubble_swap(grades, SIZE);

    return 0;
}

// This function prints the array
void print_grades(const int grades[], int size) {
    printf("My grades are:\n");
    for (int i = 0; i < size; i  ) {
        printf("%i\t", grades[i]);
    }
    printf("\n");
}

// This function calculates the average of the array
void average(const int grades[], int size) {
    double sum = 0.0;
    for (int i = 0; i < size; i  ) {
        sum  = grades[i];
    }
    printf("\nMy average grade is: %.1f\n", sum / size);
}

// This function swaps two ints
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// This is the bubble sort function.
void bubble_swap(int grades[], int size) {
    for (int i = 0; i < size; i  ) {
        for (int j = 0; j < size - 1; j  ) {
            if (grades[j] > grades[j   1]) {
                swap(&grades[j], &grades[j   1]);
            }
        }
    }
    printf("\nMy sorted grades are:\n");
    for (int i = 0; i < size; i  ) {
        printf("%i\t", grades[i]);
    }
    printf("\n");
}

CodePudding user response:

Bubble sort is working correctly but sometimes it aborts

That's like the definition of "not working correctly".

PS. I am new to C. I don't remember encountering any issues like this with python.

Python has an entirely different philosophy to C: Python tries to be friendly, and does lots of checking for you. If there is a bug, you'll probably get a helpful exception that points you to the place it went wrong.

C tries to be fast and assumes you know what you're doing. It doesn't check anything because checks take time (and if you do know what you're doing, you either don't need them or can write them yourself). You shouldn't rely on the compiler catching any errors for you at all, by default.

You can and should enable lots of compiler warnings that aren't on by default though (something like -Wall -Werror -Wextra for GCC or clang will perform a lot more static checking without slowing down the compiled executable).

I know this is a memory issue but I'm just not entirely sure how to fix it.

Because C is relatively unfriendly, there are plenty of tools to help. They're just not running by default because they make the program slower.

You can try running your program as-is under valgrind, or you can rebuild it with an address sanitizer, if your compiler offers one. Either will give you a lot of information about what is happening.

Should I be using a long for the array or a float?

You should use the type you need. Use float or double if you actually need fractional numbers. It won't fix your current problem anyway.

Should I be making the array size larger?

Ideally you want to have a hypothesis about what's actually going wrong before you start randomly changing things.

    const int SIZE = 10;
    int grades[SIZE] = { 67, 56, 65, 76, 32, 14, 59, 34, 6, 77 };

Writing it this way makes it really easy to accidentally mismatch SIZE and the number of elements. It's idiomatic to use

    int grades[] = { 67, 56, 65, 76, 32, 14, 59, 34, 6, 77 };
    const size_t ngrades = sizeof(grades)/sizeof(grades[0]);

(or wrap it in a macro like #define NELEM(a) (sizeof(a)/sizeof(a[0])))

and learning idiomatic C is just as useful as writing Pythonic Python.


Canonically, bubble sort should run until no elements are exchanged. So, this outer loop:

    for (i = 0; i < size; i  )

is wrong (although it's not the source of your memory bug).

Just reading the sort function, lines like

            if (grades[j] < grades[j 1])

jump out as possible problems. When j==size-1 on the last iteration, you're looking at grades[size] which is out of bounds.

As an aside, the statement NULL; doesn't do anything, but it's not idiomatic, and there isn't really an equivalent of Python's pass. Maybe write ; /* NO OP */ or something to indicate a deliberately empty statement (or just reverse the if statement and omit it entirely).


Anyway, the key fix is just reducing the loop upper bound by 1. Either valgrind or an address sanitizer would have shown you going off the end of the array directly. With the outer condition corrected as well, it looks something like:

void bubblesort(int *a, size_t n)
{
    bool swapped = false;
    do {
        swapped = false;
        for (size_t i = 0; i < n - 1; i  ) {
            if (a[i] > a[i 1]) {
                swapped = true;
                swap(&a[i], &a[i 1]);
            }
        }
    } while(swapped);
}
  • Related