Search code examples
carraysbubble-sortselection-sort

Array stores same number form a list of numbers twice


What my program does is that it takes an array of numbers that were read in from a file and sorts them with the selection sort and bubble sort methods. When it's sorted via the bubble sort method, the array lists one number twice in a row. It's also always the second number that gets copied. I checked to see if for whatever reason the number was actually getting passed to the new array twice, but it isn't. I also tried a different input file, same thing happens in the same place.This also cuts off the last number in the list. I don't see anything obvious in my code that's causing that to happen.

The list that the program calls is as follows:

10

50

78

83

92

100

0

4

72

3

19

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int findMin(int arr[], int start, int size);
void printArr(int arr[], int size);
void selectionSort(int arr[], int size);
void bubbleSort(int arr[], int size);

int main(int argc, char *argv[])
{
    if(argc != 2)
    {
        printf("Syntax Error: ./<exec> <infile>\n");
        exit(1);
    }

    FILE *ifp = NULL;
    ifp = fopen(argv[1], "r");

    if(ifp == NULL)
    {
        printf("Could not open %s for reading\n", argv[1]);
        exit(1);
    }

    int counter;
    int j = 0;

    fscanf(ifp, "%d", &counter);

    int array[counter];
    int arrB[counter];
    for(j = 0; j < counter; ++j)
    {
        fscanf(ifp, "%d", &array[j]);
    }

    for(j = 0; j < counter; j++)
    {
        arrB[j] = array[j];
    }
    int size = sizeof(array) / sizeof(int);

    printf("Before: ");
    printArr(array, size);

    selectionSort(array, size);
    bubbleSort(arrB, size);

    fclose(ifp);

    return 0;
}
int findMin(int arr[], int start, int size)
{
    int i = 0;
    int minLoc = start;
    int minVal = arr[minLoc];

    for ( i = start + 1; i < size; ++i)
    {
        if (arr[i] < minVal)
        {
            minVal = arr[i];
            minLoc = i;
        }
    }

    return minLoc;
}

void printArr(int arr[], int size)
{
    int i = 0;

    for(i = 0; i < size; ++i)
        printf("%3d ", arr[i]);
    printf("\n");
}
void selectionSort(int arr[], int size)
{
    int i = 0;
    int minLoc = 0;
    int tmp = 0;
    for(i = 0; i < size; ++i)
    {
        minLoc = findMin(arr, i, size);
        tmp = arr[i];
        arr[i] = arr[minLoc];
        arr[minLoc] = tmp;
    }

    printf("** Selection Sort **\n After: ");
    printArr(arr, size);

}
void bubbleSort(int arr[], int size)
{
    int i = 0;
    int j = 0;
    int tmp = 0;

    for(j = 0; j < size; j++)
    {
        for(i = 0; i < size; ++i)
        {
            if(arr[i] > arr[i+1])
            {
                tmp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = tmp;
            }
        }
    }
    printf("** Bubble Sort **\n After: ");
    printArr(arr, size);

}

Solution

  • bubbleSort() accesses outside array bounds. Thus undefined behavior (UB).

    for(j = 0; j < size; j++) {
        for(i = 0; i < size; ++i) {
            if(arr[i] > arr[i+1]) {   // Here code access outside bounds when i = size - 1
                ... Code swaps arr[i], arr[i+1];
            }
        }
    }
    

    Instead

    for(j = 0; j < size; j++) {
        for(i = 1; i < size; ++i) {
            if(arr[i-1] > arr[i]) {
                ... Code swaps arr[i-1], arr[i];
            }
        }
    }