简体   繁体   中英

How to fix “Program received signal SIGSEGV, Segmentation fault.” while trying to access an array

I'm doing quick sorting with different methods of selecting pivots, I don't see any problems in my code, the functions work while testing separated, but when I put them together, they don't work most of the time.

I've tried moving the files to another path, and changing the way I access the array.

void quick_sort(uint32_t arr[], int first, int last, int pivot_opt)
{
    int i, j;
    uint32_t pivot = pivot_select(arr, last, pivot_opt);    

    i = first;
    j = last;

    do
    {
        comparations_count++;
        while (arr[i] < pivot) i++;             // Counting elements smaller than pivot

        comparations_count++;
        while (arr[j] > pivot) j--;             // Counting elements greater than pivot         

        comparations_count++;
        if (i <= j)
        {   
            exchanges_count++;
            swap(&arr[i++], &arr[j--]);         // Placing smaller elements in the left, and greater elements in the right without touching the pivot
        }

        comparations_count++;
    } while (i <= j);

    comparations_count++;
    if (first < j)
        quick_sort(arr, first, j, pivot_opt);   // Sorting smaller elements of array

    comparations_count++;
    if (i < last)
        quick_sort(arr, i, last, pivot_opt);    // Sorting greater elements of array

}

uint32_t pivot_select(uint32_t arr[], int last, int pivot_opt)
{   
    uint32_t pivot = 0;
    int random_index = 0;
    switch (pivot_opt)
    {
    case 0:     
        pivot = arr[last];                          // Choosing the pivot as the last element in the array
        break;
    case 1:     
        random_index = rand()%(last);               // Choosing the pivot as a random element of array
        pivot = arr[random_index];
        break;
    case 2:     
        pivot = median(arr, last);                  // Choosing the pivot as avg of three random indexes of the array
        break;
    default:
        break;
    }
    return pivot;
}

uint32_t median(uint32_t arr[], int n)
{
    if (n <= 3)
    {   
        return arr[0];                                                      // If the array have 3 or less elements, choose as pivot first element
    }
    else
    {
        int index[3] = {0};                                                 // Index of 3 elements of original array
        int last_index = 0;                                                 // Last chosen index, to verify if index was selected
        int i = 0;

        while(i < 3)                                                        // Selecting 3 random index
        {
            int current_index = (rand()%(n));
            if (current_index == last_index)    
                i--;
            else
            {
                index[i++] = current_index;
                last_index = current_index;
            }           
        }

        uint32_t array[3] = {arr[index[0]], arr[index[1]], arr[index[2]]};  // Creating array with the elements on random indexes
        insertion_sort(array, 3);                                           // Sorting the array
        return array[1];                                                    // Returning the pivot as the middle element of array
    }

}

I'm getting this error on median function

Program received signal SIGSEGV, Segmentation fault.
0x0000555555555546 in median (arr=<error reading variable: Cannot access memory at address 0x7fffff7fefd8>, n=<error reading variable: Cannot access memory at address 0x7fffff7fefd4>) at /media/storage/Codes/Data Structure/Recursive_Sorting/main.c:107
107 {

I put all the libraries I'm using so I don't miss one. Code for testing:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>
#include <time.h>
#define size 1000

uint32_t comparations_count;
uint32_t exchanges_count;
int main(int argc, char** argv)
{   
    uint32_t array[size];

    fill(array, size);
    permute_array(array, size);

    comparations_count = 0;
    exchanges_count = 0;
    quick_sort(array, 0, size-1, 2);

    return 0;
}

void fill(uint32_t arr[], uint32_t n)
{       
    for (size_t i = 0; i < n; i++)              // Filling the array in ascending order
        arr[i] = i;
}

void swap(uint32_t *a, uint32_t *b)
{
    // Swapping two elements
    uint32_t t = *a;
    *a = *b;
    *b = t;
}

void permute_array(int a[], size_t n)
{
    // Adapted from:
    // https://www.geeksforgeeks.org/shuffle-a-given-array-using-fisher-yates-shuffle-algorithm/

    srand(time(NULL));                          // Init random seed

    for (size_t i = n - 1; i > 0; i--)          // Permute array
    {        
        size_t j = rand() % (i+1);              // Pick a random index from 0 to i        
        swap(&a[i], &a[j]);                     // Swap arr[i] with the element at random index
    }
}

void insertion_sort(uint32_t arr[], size_t n)
{
    uint32_t current_index = 0;
    uint32_t current_value = 0;

    for (size_t i = 1; i < n; i++) {
        current_index = i;
        current_value = arr[i];
        while (current_index > 0) {
            if (current_value < arr[current_index - 1]) {
               swap(&arr[current_index], &arr[current_index-1]);
               current_index--;
            }else { break; }            
        }     
    }
}

Let's start with this one:

while (arr[i] < pivot) i++;

What if all the elements are less than pivot, your i will be out of bounds, change the condition to while(arr[i] < pivot && i <= j) i++;

Consider this one:

while (arr[j] > pivot) j--; 

What if all the elements are greater than pivot, your j will be out of bounds (a negative number), change the condition here too.

According to my opinion, the above-mentioned areas are causing problems.

Happy debugging!

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