简体   繁体   中英

Seg Fault calling mergesort on pointer array

I am trying to work with threads in C. I need one of my threads to work on one half of a whole array, and mergesort its half. To do this I created a global array pointer for the whole array and both halves. The is allocated at runtime with malloc .

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

void *process1(void *arg);
void *process2(void *arg);
void *process3(void *arg);
void *process4(void *arg);
void *process5(void *arg);

void merge(int *arr, int l, int m, int r);
void mergeSort(int *arr, int l, int r);

int *array;
int *arr_first;
int *arr_second;
int arr_s;
size_t n_size;
int n_size_i;
pthread_mutex_t mutex;

main(int argc, char *argv[]) {

    arr_s = atoi(argv[1]);

    n_size = arr_s / 2;
    n_size_i = arr_s / 2;
    
    array = malloc (arr_s * sizeof (int));  
    
    arr_first = malloc(arr_s / 2 * sizeof(int));

    if (arr_s % 2 == 0)
        arr_second = malloc((n_size) * sizeof (int));
    else
        arr_second = malloc((n_size+1) * sizeof(int));
    
    pthread_t tid1, tid2, tid3, tid4, tid5;
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_mutex_init(&mutex, NULL);

    pthread_create(&tid1, &attr, process1, NULL);
    pthread_join(tid1, NULL);

    printf("---------------------------------------------------------------------------THREAD 2 AND 3 ARE CURRENTLY SORTING THE NUMBERS-------------------------------------------------------------------------\n");

    pthread_create(&tid2, &attr, process2, NULL);
    pthread_create(&tid3, &attr, process3, NULL);
    
    pthread_join(tid2, NULL);
    pthread_join(tid3, NULL);

    pthread_create(&tid4, &attr, process4, NULL);   
    pthread_join(tid4, NULL);

    pthread_create(&tid5, &attr, process5, NULL);
    pthread_join(tid5, NULL);

    free(array);
    free(arr_first);
    free(arr_second);
    exit(0);    
}

Here is what the function looks like for my thread im having trouble on (thread 2) At the moment, all it does it takes the first half of the whole array, and one by one takes the value and places it into its own. Then i print out the array. Then finally call mergesort on the array pointer.

void *process2(void *arg) {
    int j = 0;
    for (; j < (arr_s / 2); j++) {
        arr_first[j] = array[j];
    }

    int j2;
    for (j2 = 0; j2 < (arr_s / 2); j2++) {
        printf("*%d\t", arr_first[j2]);
        if ((j2 + 1) % 25 == 0 && j2 > 0)
            printf("\n");
    }   
    
    mergeSort(arr_first, 0, (arr_s / 2) - 1);
        
    pthread_exit (0);
}

Here are my merge and mergeSort functions:

//Merges two subarrays of arr[]
//First subarry is arr[l..m]
//Second subarry is arr[m+1..r]
void merge(int *arr, int l, int m, int r) {
    int i, j, k;
    int n1 = m - l + 1;
    int n2 = r - m;

    //create temp arrays
    int L[n1], R[n2];

    //copy data to temp array L[] and R[]
    for (i = 0; i < n1; i++)
        L[i] = arr[l+i];
    for (j = 0; j < n2; j++)
        R[j] = arr[m + 1 + j];

    //merge the temp arrays back in arr[l..r]
    i = 0; j = 0; k = l;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    //copy remaining elements of L[], if there are any
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }
    
    //same for R[]
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

void mergeSort(int *arr, int l, int r) {
    if (l < r) {
        int m = 1 + (r - 1) / 2;

        //Sort first and second halves
        mergeSort(arr, l, m);
        mergeSort(arr, m + 1, r);

        merge(arr, l, m, r);
    }
}

For some reason when I call merge sort, it will keep recursively calling many more times than there are even elements in the array. I put a print statement before anything else in the mergeSort function, and the print statement executes 50000+ times maybe more. However, if I put a print statement right before the merge call inside mergeSort it never gets executed.

The computation for the middle point in mergeSort is incorrect: there is a confusion between l and 1 . It should be:

    int m = l + (r - l) / 2;

Naming a variable l is very error prone. Use left or low instead:

void mergeSort(int *arr, int left, int right) {
    if (left < right) {
        int m = left + (right - left) / 2;

        //Sort first and second halves
        mergeSort(arr, left, m);
        mergeSort(arr, m + 1, right);

        merge(arr, left, m, right);
    }
}

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