【问题标题】:How to fix the Segmentation Fault in C如何修复 C 中的分段错误
【发布时间】:2021-07-18 06:15:23
【问题描述】:

我正在编写一个程序来使用递归查找最大数量的数组。返回分段错误。我对此做了一些研究。事实证明,访问超出给定长度的数组是有问题的。我不知道如何解决这个错误。更具体地说,我不知道如何设置允许数组具有特定用户提供长度的参数。我也不知道如何表达它的论点。 这是我的代码:

#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);
}

【问题讨论】:

  • 1.我会使用 INT_MIN(包括 limits.h)而不是 -999999 2. 你的函数 findLargest() 永远不会返回 - 它应该有一些返回语句。我把它留给你做作业来正确放置它们。
  • 您的 findLargest 函数是递归的,并且没有退出递归函数的基本条件,因此它一次又一次地调用该函数并导致分段错误。
  • (i &lt;n) 不是基本条件吗?因为用户将指定长度 (n)。递归将循环直到 i
  • 另外,我现在添加了return语句。谢谢@ivan.ukr
  • Re "Isn't (i ", 即使i&lt;n, findLargest 仍然被递归调用。也许它应该是基本条件,但它不是。

标签: arrays c recursion max function-definition


【解决方案1】:

你必须在递归函数中返回一些值,并在参数中通过引用传递变量。 int findLargest(int n, int arr[])

按值传递变量不会改变变量的原始值(这里是最大的),它只是创建该变量的新副本并为其赋值。 以下代码工作正常

 #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);
    }
}

【讨论】:

    【解决方案2】:

    你的函数定义

    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);
    }
    

    没有意义。

    例如,用户可以为第一个参数传递一个非正数。 其次,数组可以包含小于幻数-9999999 的值。

    这个作业

    x = arr[i];
    

    没有效果,因为在函数的每次递归调用中,变量 x 被重新初始化为值 -9999999

    int x = -9999999;
    

    同样静态变量i只初始化一次

    static int i = 0;
    

    然后再次调用该函数会导致未定义的行为,因为变量未重置。

    更重要的是该函数没有返回语句。

    函数应该像这样声明

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

    即第一个参数应具有限定符const,并表示在函数内未更改的传递数组。第二个参数的类型为size_t

    函数返回传递数组的最大元素的索引。

    这是函数定义。

    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;
        }
    }
    

    为了减少函数的递归调用次数,您可以将传递的数组分成两部分,并为每一部分调用函数。

    这是一个演示程序。

    #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;
    }
    

    程序输出可能看起来像

    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
    

    下面展示了可以为任何类型的数组调用的通用递归函数的外观

    #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;
    }
    

    同样,程序输出可能是

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-15
      • 2019-03-31
      • 2019-06-20
      • 1970-01-01
      相关资源
      最近更新 更多