简体   繁体   English

为什么会出现分段错误 11?

[英]Why do i get segmentation fault 11?

Why do I get segmentation fault 11?为什么会出现分段错误 11? I get it quite often, and I know this time it is about the function.我经常得到它,我知道这次是关于 function。 If anyone can help, please do, the code is down below, I am trying to make a program, that WITH A FUNCTION.如果有人可以帮忙,请做,代码在下面,我正在尝试制作一个带有 FUNCTION 的程序。 can rearrange an array in ascending order and then print it in main in reverse order.可以按升序重新排列数组,然后以相反的顺序在 main 中打印。

#include "stdio.h"

void changxr(int *counter, int *arrsize, int *j, int *arr[]);

int main()
{
    int a, i, j, counter;
    int arrsize;
    int arr[100];
    printf("pick an arraysize: \n");
    scanf("%d", &arrsize);
    printf("type %d numbers \n", arrsize);
    for (counter = 0; counter < arrsize; counter++)
    {
        scanf("%d", &arr[counter]);
    }

    for (int c = arrsize - 1; c >= 0; c--)
    {
        printf("%d ", arr[c]);
    }

    changxr(&counter, &arrsize, &j, &arr[&counter]);

    for (counter = arrsize - 1; counter >= 0; counter--)
    {
        printf("%d ", arr[counter]);
    }
}

void changxr(int *counter, int *arrsize, int *j, int *arr[])
{
    int a;
    for (*counter = 0; *counter < *arrsize; *counter++)
    {
        for (*j = *counter + 1; *j < *arrsize; *j++)
        {
            if (*arr[*counter] > *arr[*j])
            {
                a = *arr[*counter];
                *arr[*counter] = *arr[*j];
                *arr[*j] = a;
            }
        }
    }
}

New code:新代码:

#include "stdio.h"

void changxr(int arrsize, int *arr[]);

int main()
{
    int a, i, j, counter;
    int arrsize;
    int arr[100];
    printf("pick an arraysize: \n");
    scanf("%d", &arrsize);

    printf("type %d numbers \n", arrsize);
    for (counter = 0; counter < arrsize; counter++)
    {
        scanf("%d", &arr[counter]);
    }

    for (int c = arrsize - 1; c >= 0; c--)
    {
        printf("%d ", arr[c]);
    }

    changxr(arrsize, &arr[counter]);

    for (counter = arrsize - 1; counter >= 0; counter--)
    {
        printf("%d ", arr[counter]);
    }
}

void changxr(int arrsize, int *arr[])
{
    int a, counter, j;
    for (counter = 0; counter < arrsize; counter++)
    {
        for (j = counter + 1; j < arrsize; j++)
        {
            if (*arr[counter] > *arr[j])
            {
                a = *arr[counter];
                *arr[counter] = *arr[j];
                *arr[j] = a;
            }
        }
    }
}

This is what I got from debugging:这是我从调试中得到的:

"Program received signal SIGSEGV, Segmentation fault.
0x0000555555555355 in changxr (arrsize=3, arr=0x0) at main.c:33
33              for(j=counter+1; j<arrsize; j++) { if(*arr[counter]>*arr[j]){
(gdb) continue"

You do not need two levels of indirection ( int *arr[] , *arr[counter] , *arr[j] ).您不需要两个级别的间接( int *arr[]*arr[counter]*arr[j] )。 When arr is passed to a function, it will decay to a pointer-to-its-first-element, or more simply, an int * .arr被传递给 function 时,它将衰减为指向其第一个元素的指针,或者更简单地说,一个int *

&arr[counter] is also an int * , but it is the address of the array element one past the elements you've initialized. &arr[counter]也是一个int * ,但它是数组元素的地址,超过了您已初始化的元素。 This would start your sorting function in the incorrect place.这将在不正确的位置开始您的排序 function。

Your program segfaults because it attempts to use this value as an int ** ( int *[] ).您的程序会出现段错误,因为它尝试将此值用作int ** ( int *[] )。

gcc -Wall highlights this clearly: gcc -Wall清楚地强调了这一点:

prog.c: In function ‘main’:
prog.c:24:22: warning: passing argument 2 of ‘changxr’ from incompatible pointer type [-Wincompatible-pointer-types]
   24 |     changxr(arrsize, &arr[counter]);
      |                      ^~~~~~~~~~~~~
      |                      |
      |                      int *
prog.c:3:32: note: expected ‘int **’ but argument is of type ‘int *’
    3 | void changxr(int arrsize, int *arr[]);
      |                           ~~~~~^~~~~

Things to do:要做的事情:

  • Simply pass the array and the length of the array to your function.只需将数组和数组长度传递给您的 function。
  • Use a single level of indirection in your function definition, and when accessing the array.在 function 定义中和访问数组时使用单级间接。
  • Use a variable-length array .使用变长数组
  • Use an auxiliary function for printing.使用辅助 function 进行打印。
  • Declare variables when you need them, in the correct scope.在需要时在正确的 scope 中声明变量。

You should also consider checking the return value of scanf is the expected number of successful conversions .您还应该考虑检查scanf的返回值是预期的成功转换次数。

The refactored code:重构后的代码:

#include <stdio.h>

void changxr(int *a, size_t length)
{
    for (size_t i = 0; i < length; i++) {
        for (size_t j = i + 1; j < length; j++) {
            if (a[i] > a[j]) {
                int temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
    }
}

void print_reverse(int *a, size_t length)
{
    printf("[ ");
    while (length--)
        printf("%d ", a[length]);
    printf("]\n");
}

int main(void)
{
    size_t size;

    printf("Pick an array length: ");

    if (1 != scanf("%zu", &size) || size == 0) {
        fprintf(stderr, "Invalid length input.\n");
        return 1;
    }

    int array[size];

    printf("Enter %zu numbers:\n", size);

    for (size_t i = 0; i < size; i++) {
        if (1 != scanf("%d", array + i)) {
            fprintf(stderr, "Invalid integer input.\n");
            return 1;
        }
    }

    printf("Array (in reverse): ");
    print_reverse(array, size);

    changxr(array, size);

    printf("Array, Sorted (in reverse): ");
    print_reverse(array, size);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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