C SegFault 通过打印修复?

C SegFault fixed by print?

我的任务是用 C 编写一个程序。该程序应该能够检查参数并创建与我提供的参数一样大的数组。我必须用随机数填充数组。到目前为止工作正常。稍后我的任务是使用指针对数组进行排序。第一件事是我不太明白指针是如何工作的,但到目前为止我已经完成了排序工作。唯一的问题是,我只能对 4 的大小进行排序。如果我的参数大于 4,我将对前 4 个数字进行排序,然后出现分段错误。我找不到问题,但有趣的是,如果我添加一个 printf 只是为了再次打印我的参数,它对我想要的任何参数都可以正常工作!我不知道发生了什么!

这里又是确切的任务,因为我觉得我描述得不够好:

To do this, create a dynamic pointer field of the same size and initialize it with pointers to the elements of the int field. When sorting, the pointers should now be sorted so that the first pointer points to the smallest int value, the second to the next largest value, and so on.

int main(int argc, char *argv[]) {
    
    int *array;
    int **arrpointer;
    
    int size = atoi(argv[1]);
     
    if (size == 0) {
        fprintf(stderr, "Wrong parameter!\n");
        return EXIT_FAILURE;
    }

    //printf("Array-Size : ");   //First I had it with scanf, which works perfectly fine without a print
    //scanf("%d", &size);

    printf("Input%d", size);  //This is the print I need somehow!

    // allocate memory
    array = (int *)malloc(size * sizeof(int));        // Init Array
    arrpointer = (int **)malloc(size * sizeof(int));  // Init Pointer Array

    //Check Pointer array 
    if (arrpointer != NULL) {
        printf("Memory allocated\n\n");
    } else {
        fprintf(stderr, "\nNo free memory.\n");
        return EXIT_FAILURE;
    }
    
    if (array != NULL) {
        printf("Memory is allocated\n\n");

        //Fill Array
        for (int i = 0; i < size; i++) {
            array[i] = rand() % 1000; //I know it is not random right now, will add later
            int *temp = &array[i];
            arrpointer[i] = temp;     //Pointer fill
        } 
    } else {
        fprintf(stderr, "\nNo free memory to allocate.\n");
        return EXIT_FAILURE;
    }
    shakersort(arrpointer, size);  //Function to sort pointers
    zeigeFeld(arrpointer, size);  //Function to Print
        
    free(array);
    free(arrpointer);
    return EXIT_SUCCESS;
} 

我知道这有点混乱,对不起。 我还将在下面的排序位置添加代码。

void swap(int **a, int **b) {

    int ram;
    ram = **a;
    **a = **b;
    **b = ram;
}

void shakersort(int **a, int n) {
    int p, i;
    for (p = 1; p <= n / 2; p++) {
        for (i = p - 1; i < n - p; i++)
            if (*a[i] > *a[i+1]) {
                swap(&a[i], &a[i + 1]);
            }
           
        for (i = n - p - 1; i >= p; i--)
            if (*a[i] < *a[i-1]) {
                swap(&a[i], &a[i - 1]);                
            }           
    }
}

这是我尝试为指针构建的代码,目前运行良好。

我希望有人可以帮助或提供一些意见,说明为什么我的印刷品可以解决问题。我真的不明白! 感谢您的宝贵时间和帮助,如果我需要添加任何内容,请告诉我!

为什么在printf之前使用指针?? 首先你需要知道指针是什么: 指针是某种变量,其中包含另一个变量的地址。

例如:

int b = 2;

int * a = &b;

a变量包含变量b的地址。然后如果你打印 ((a)) 它会给你十六进制数,它是 b 的地址。如果您打印 ((*a)),编译器将在地址中打印变量 a 的内容,并在单元格 b 的地址中打印数字的数量(即 2)。

现在我猜你明白指针是什么了,再看看你的代码并改正错误。

程序有未定义的行为,因为数组的分配大小不正确:

arrpointer = (int **)malloc(size * sizeof(int));

size 整数分配 space,但它应该为 size 指向 int 的指针分配 space,这在 64 位系统上更大比 int。改用这个:

arrpointer = (int **)malloc(size * sizeof(int *));

或者使用目标指针的类型:

arrpointer = malloc(sizeof(*arrpointer) * size);

后一种语法更安全,因为它适用于任何非 void 指针类型。

但是请注意,这个指针数组对于您的目的来说有点过分了。您应该只在 int:

的数组上实现排序功能
void swap(int *a, int *b) {
    int ram = *a;
    *a = *b;
    *b = ram;
}

void shakersort(int *a, int n) {
    int p, i;
    for (p = 1; p <= n / 2; p++) {
        for (i = p - 1; i < n - p; i++) {
            if (a[i] > a[i + 1]) {
                swap(&a[i], &a[i + 1]);
            }
        }
        for (i = n - p - 1; i >= p; i--) {
            if (a[i] < a[i - 1]) {
                swap(&a[i], &a[i - 1]);                
            }
        }          
    }
}

我不清楚上面的代码是否真的对数组进行了排序,我从不使用 shakersort。

我从

更新了我的代码
arrpointer = (int **) malloc(size * sizeof(int));

arrpointer = malloc(sizeof *arrpointer * size);

而且效果很好! 谢谢大家的帮助!