简体   繁体   中英

How to fix the Segmentation Fault in C

I'm writing a program to find the largest number of an array using recursion. The returns a segmentation fault. I did some research on it. It turns out that there is something with accessing the array out of the given length. I don't know how to fix this error. More specifically, I don't know how to set a parameter that allows an array in a specific user-provided length. Also I don't know how to represent the argument of it. Here's my code:

#include <stdio.h>

int findLargest(int, int[]);

int main() {
    int n;
    printf("Input the number of elements to be stored in the array: ");
    scanf("%d", &n);
    int arr[n];
    printf("Input %d elements in the array: \n", n);
    for (int i = 0; i < n; ++i) {
        printf("element - %d: ", i);
        scanf("%d", &arr[i]);
    }
    printf("Largest element of an array is: %d", findLargest(n, arr));
}

int findLargest(int n, int arr[]) {
    static int i = 0;
    int x = -9999999;
    if (i < n) {
        if (arr[i] > x)
            x = arr[i];
        printf("%d\n", i);
        ++i;
    }
    findLargest(n, arr);
}

Your function definition

int findLargest(int n, int arr[]) {
    static int i = 0;
    int x = -9999999;
    if (i < n) {
        if (arr[i] > x)
            x = arr[i];
        printf("%d\n", i);
        ++i;
    }
    findLargest(n, arr);
}

does not make a sense.

For example the user can pass for the first parameter a non-positive number. Secondly the array can contain values that are less than the magic number -9999999 .

This assignment

x = arr[i];

does not have an effect because in each recursive call of the function the variable x is initialized anew by the value -9999999

int x = -9999999;

Also as the static variable i is initialized only once

static int i = 0;

then calling the function a second time results in undefined behavior because the variable is not reset.

And more importantly the function does not have a return statement.

The function should be declared like

size_t findLargest( const int a[], size_t n );

that is the first parameter shall have the qualifier const and denote the passed array that is not changed within the function. The second parameter shall have the type size_t .

The function returns the index of the maximum element of the passed array.

Here is the function definition.

size_t findLargest( const int a[], size_t n )
{
    if ( n <  2 )
    {
        return 0;
    }
    else
    {
        size_t n1 = 1 + findLargest( a + 1, n - 1 );
        return a[0] < a[n1] ? n1 : 0;
    }
}

To reduce the number of recursive calls of the function you can split the passed array into two parts and call the function for each part.

Here is a demonstrative program.

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

size_t findLargest( const int a[], size_t n )
{
    if ( n < 2 )
    {
        return 0;
    }
    else
    {
        size_t n1 = findLargest( a, n / 2 );
        size_t n2 = n / 2 + findLargest( a + n / 2, n - n / 2 );
        
        return a[n1] < a[n2] ? n2 : n1;
    }
}

int main(void) 
{
    srand( ( unsigned int )time( NULL ) );

    while ( 1 )
    {
        printf( "Input the number of elements to be stored in the array (0 - exit): " );
        
        size_t n;
        
        if ( scanf( "%zu", &n ) != 1 || n == 0 ) break;
        
        int a[n];
        
        for ( size_t i = 0; i < n; i++ ) a[i] = rand() % ( 2 * n );
        
        for ( size_t i = 0; i < n; i++ )
        {
            printf( "%d ", a[i] );
        }
        putchar( '\n' );
        
        printf( "The largest element of the array is: %d\n", a[findLargest( a, n )] );
    }
    
    return 0;
}

The program output might look like

Input the number of elements to be stored in the array (0 - exit): 10
5 14 0 4 19 8 2 1 11 6 
The largest element of the array is: 19
Input the number of elements to be stored in the array (0 - exit): 9
9 3 12 15 4 13 17 13 7 
The largest element of the array is: 17
Input the number of elements to be stored in the array (0 - exit): 8
2 13 9 11 12 8 14 3 
The largest element of the array is: 14
Input the number of elements to be stored in the array (0 - exit): 7
13 5 0 2 8 6 1 
The largest element of the array is: 13
Input the number of elements to be stored in the array (0 - exit): 6
10 7 11 5 1 7 
The largest element of the array is: 11
Input the number of elements to be stored in the array (0 - exit): 5
9 0 4 1 1 
The largest element of the array is: 9
Input the number of elements to be stored in the array (0 - exit): 4
2 0 6 5 
The largest element of the array is: 6
Input the number of elements to be stored in the array (0 - exit): 3
1 1 2 
The largest element of the array is: 2
Input the number of elements to be stored in the array (0 - exit): 2
1 0 
The largest element of the array is: 1
Input the number of elements to be stored in the array (0 - exit): 1
0 
The largest element of the array is: 0
Input the number of elements to be stored in the array (0 - exit): 0

Below there is shown how such a general recursive function that can be called for an array of any type can look

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

size_t findLargest( const void *base, 
                    size_t nmemb, 
                    size_t size, 
                    int cmp( const void *, const void * ) )
{
    if ( nmemb < 2 )
    {
        return 0;
    }
    else
    {
        size_t nmemb1 = findLargest( base, nmemb / 2, size, cmp );
        size_t nmemb2 = nmemb / 2 + 
                        findLargest( ( const char * )base + nmemb / 2 * size, 
                                     nmemb - nmemb / 2, size, cmp );
        
        return cmp( ( const char * )base + nmemb1 * size, 
                    ( const char * )base + nmemb2 * size ) < 0
               ? nmemb2 : nmemb1;
    }
}

int cmp( const void *a, const void *b )
{
    int left  = *( const int * )a;
    int right = *( const int * )b;
    
    return ( right < left ) - ( left < right );
}

int main(void) 
{
    srand( ( unsigned int )time( NULL ) );
    while ( 1 )
    {
        printf( "Input the number of elements to be stored in the array (0 - exit): " );
        
        size_t n;
        
        if ( scanf( "%zu", &n ) != 1 || n == 0 ) break;
        
        int a[n];
        
        for ( size_t i = 0; i < n; i++ ) a[i] = rand() % ( 2 * n );
        
        for ( size_t i = 0; i < n; i++ )
        {
            printf( "%d ", a[i] );
        }
        putchar( '\n' );
        
        size_t i = findLargest( a, n, sizeof( *a ), cmp );
        printf( "The largest element of the array is: %d\n", a[i] );
    }
    
    return 0;
}

Again the program output might be

Input the number of elements to be stored in the array (0 - exit): 10
6 2 5 5 3 1 4 1 10 9 
The largest element of the array is: 10
Input the number of elements to be stored in the array (0 - exit): 9
9 7 1 11 5 16 8 2 8 
The largest element of the array is: 16
Input the number of elements to be stored in the array (0 - exit): 8
4 8 1 0 10 15 9 1 
The largest element of the array is: 15
Input the number of elements to be stored in the array (0 - exit): 7
13 0 4 9 3 4 4 
The largest element of the array is: 13
Input the number of elements to be stored in the array (0 - exit): 6
10 1 0 6 2 2 
The largest element of the array is: 10
Input the number of elements to be stored in the array (0 - exit): 5
5 4 3 4 5 
The largest element of the array is: 5
Input the number of elements to be stored in the array 4
(0 - exit): 3 4 3 5 
The largest element of the array is: 5
Input the number of elements to be stored in the array (0 - exit): 3
0 5 5 
The largest element of the array is: 5
Input the number of elements to be stored in the array (0 - exit): 2
0 0 
The largest element of the array is: 0
Input the number of elements to be stored in the array (0 - exit): 1
0 
The largest element of the array is: 0
Input the number of elements to be stored in the array (0 - exit): 0

You have to return some value in the recursive function and pass variables by reference in the parameter. int findLargest(int n, int arr[])

Passing a variable by value won't alter the original value of variables (here largest), it just creates a new copy of that variable and assigns value to it. The following code works fine

 #include <stdio.h>
    int findLargest(int[], int, int);

    int main(){
   

     int n;
        int largest;
        int i;
    
        printf("Input the number of elements to be stored in the array: ");
        scanf("%d", &n);
        int arr[n];
        printf("Input %d elements in the array: \n", n);
        for (int i = 0; i < n; ++i) {
            printf("element - %d: ", i);
            scanf("%d", &arr[i]);
        }
    
        if (n == 0){
            printf("Empty list\n");
        }

    else{
        largest = arr[0];
        largest = findLargest(arr, n - 1, largest);
        printf("\nThe largest number in the list is: %d\n", largest);
    }
}

int findLargest(int arr[], int position, int largest){
    if (position == 0)
        return largest;
    if (position > 0){
        if (arr[position] > largest){
            largest = arr[position];
        }
        return findLargest(arr, position - 1, largest);
    }
}

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