简体   繁体   中英

Function to remove an element from a sorted array

I have some problem with removing an element from a sorted array (all instances of an element must be removed). When I run my program, I get a segmentation fault. I have no idea why that happens, because the function remElem(int*, int*, int) where 1st arg is an array, 2nd arg is a length of an array (which changes when elements are removed) and 3rd arg is an element to be removed -- worked properly before I expanded the program with switch statement and onther functions like shuffle(int*, int) (for shuffling elements of an array) and insElem(int*, int*, int) (for inserting an element into a sorted array. I have no idea what went wrong, please help. I will provide the code with comments. There are also some other minor questions provided with the comments. Thank you in advance :)

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

#define MAX_LEN 1000


void initArray(int*, int);
void printArray(int*, int);
void swap(int*, int*);
void insSort(int*, int);
void insElem(int*, int*, int);
void remElem(int*, int*, int);
void shuffle(int*, int);


int main() {
    int array[MAX_LEN];
    int len, elem, comm;

    srandom(time(NULL));

    printf("Number of elements? >> ");
    scanf("%d", &len);

    initArray(array, len);

    do {
        printf("Command? (6 for help) >> ");
        scanf("%d", &comm);
        switch (comm) {
            case 1:
                printArray(array, len);
                break;
            case 2:
                shuffle(array, len);
                break;
            case 3:
                insSort(array, len);
                break;
            case 4:
                printf("Insert element? >> ");
                scanf("%d", &elem);
                insElem(array, &len, elem);
                break;
            case 5:
                printf("Remove element? >> ");
                scanf("%d", &elem);
                remElem(array, &len, elem);
                break;
            case 6:
                printf("Help:\n");
                printf("1 - Print\n");
                printf("2 - Shuffle\n");
                printf("3 - Sort\n");
                printf("4 - Insert element\n");
                printf("5 - Remove element\n");
                printf("6 - Help (this screen)\n");
                printf("0 - Quit\n");
                break;
            case 0:
                break;
            default :
                printf("Wrong input! Repeat!\n");
        }
    } while (comm);

    return EXIT_SUCCESS;
}


/*Initializes array with n random numbers from 0 to 9 (including)*/
void initArray(int a[], int n) {
    int i;

    for (i = 0; i < n; i++)
        a[i] = random() % 10;
}


/*Prints n elements of an array*/
void printArray(int a[], int n) {
    int i;

    for (i = 0; i < n; i++)
        printf("%d ", a[i]);
    putchar('\n');
}


/*Swaps the values of two variables*/
void swap(int *i, int *j) {
    *i = *i + *j;
    *j = *i - *j;
    *i = *i - *j;
    /*I saved up some memory yaaaaaaay :3 */
    /*I spent some processing time nooooo :| */
    /*Which is better... with or without tmp variable???*/
    /*I suppose it depends on application... clearly, this
      method doesnt work with structures, for example*/
}


/*Sorts the elements of an array using insertion sort algorythm*/
void insSort(int a[], int n) {
    int i, j;

    for (i = 1; i < n; i ++)
        for (j = i; j > 0 && a[j] < a[j-1]; j--)
            swap(&a[j], &a[j-1]);
}


/*Inserts an element into a sorted array*/
/*Wassn meant to be working with unsorted arrays
  in that case unpreddictable results*/
void insElem(int a[], int *n, int e) {
    int i, j;

    (*n)++;
    for (i = 0; a[i] < e && a[i+1] < e; i++);

    for (j = *n; j > i + 1; j--)
        a[j] = a[j-1];

    a[i+1] = e;
}


/*Removes an element from a sorted array*/
/*Wassn meant to be working with unsorted arrays
  in that case unpreddictable results*/
void remElem(int a[], int *n, int e) {
    int i, j;

    for (i = 0; i < *n; i++) {
        while (a[i] == e) {
            for (j = i; j < *n; j++)
                a[j] = a[j+1];
        (*n)--;
        }
    }
}


/*Shuffles the elements of an array*/
/*I just did this on the fly...
  are there any known algorythms for doing this*/
void shuffle(int a[], int n) {
    int i;

    for (i = 0; i < n; i++)
        swap(&a[rand()%n], &a[rand()%n]);
}

The following can result in out-of-bounds access, leading to undefined behaviour:

        for (j = i; j < *n; j++)
            a[j] = a[j+1];

Consider what happens to a[j+1] when j == (*n)-1 .

As to the swap() function, your clever-looking implementation is at risk of integer overflow and consequently undefined behaviour. Just use a temporary variable and let the compiler worry about efficiency.

In this cycle:

for (j = i; j < *n; j++)
  a[j] = a[j+1];

When j = *n - 1 , you will access memory that is outside of the array's bounds. This invokes undefined behavior and the result may be anything and so I believe it explains your crash. As for way the program did not crash before - well as this can do anything it may also have no negative effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM