1

情况

我试图实现一个更有趣的合并排序,它创建一个具有随机值的随机长度数组,然后将它们随机化,但是在调试和编译它之后会出现段错误。我不知道为什么会出现段错误,但我确定它与内存分配有关。

问题

为什么这段代码会导致段错误?

代码

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


// Declare some stuff up front

int array_size(int *array);
int print_array(int *array);

//Some decade old main function coming at you

int main() {

    //Concerned with the integrity of my rand
    srand( (unsigned)time( NULL ));

    //A global, random length array between 1 and 100?
    int *array;
    array = malloc(sizeof(*array) * ((rand() % 100) + 1));


    init_array(*array);




    getchar();
    return 0;
}

int init_array(int *array)  {
    //Base case
    array[0] = 1;
    //random values for i in array
    int i;
    for(i = 1; i <= array_size(array); i++)  {
          array[i] = rand() % array_size(array) + 1;
    }
    //randomize the random values in the random length array
    for (i = 0; i < (array_size(array) - 1); i++)
    {
        unsigned int swapA = (rand() % array_size(array)) + 1;
        int a = array[swapA];
        array[swapA] = array[i];
        array[i] = a;
    }
    //output random array, then mergeSort the array
    print_array(array);
    sort_array(array);
    return 0;
}

//Get my array.Length
int array_size(int *array) {
    return sizeof(array)/sizeof(array[0]);
}

//Output array
int print_array(int *array) {
     int i;
     for(i = 0; i < (array_size(array) + 1); i++) {
           printf("%d\n", array[i]);
     }
     return 0;
}
     //merge the array after sorting
void merge_array(int *array, int low, int split, int high)  {
     int sorted[high-low+1];
     int a = 0;
     int b = low;
     int c = split + 1;
     //iterate from beginning to middle and from middle to end in parallel
     while(b <= split && c <= high)
     {
            if(array[b] < array[c])
            {
                sorted[a++] = array[b++];
            }
            else
            {
                sorted[a++] = array[c++];
            }
     }

     while(b <= split) sorted[a++] = array[b++];
     while(c <= high)  sorted[a++] = array[c++];
     int i;
     for(i = 0; i < a; i++) {
           array[i+low] = sorted[i];
     }
     print_array(array);            //Print sorted array
}
     //Sort the array
int sort_array(int *array, int low, int high) {
    int split = ( low + high ) / 2;
    if( low < high ) {
        sort_array(array, low, split);
        sort_array(array, split + 1, high);
        merge_array(array, low, split, high);
    }

}
4

3 回答 3

2
return sizeof(array)/sizeof(array[0]);

上述语句的计算结果为1(假设sizeof(int *) = sizeof(int),如 H2CO3 所指出的那样)。

试试这样的,

int main() {

//Concerned with the integrity of my rand
srand( (unsigned)time( NULL ));

//A global, random length array between 1 and 100?
int *array;
int number_of_elements = (rand() % 100) + 1;
array = malloc(sizeof(*array) * num_of_elements);

init_array(*array, num_of_elements);

getchar();
return 0;

}

将元素的数量作为参数传递给init_array而不是每次都计算它。

于 2013-02-05T06:20:46.040 回答
1

这似乎是问题所在:

//Get my array.Length
int array_size(int *array) {
    return sizeof(array)/sizeof(array[0]);
}

你本质上return sizeof(int*)/sizeof(int),这不是你想要的。这整件事之所以出现是因为数组在传递给函数时会衰减为指针。

您应该阅读comp.lang.c 常见问题解答中的数组和指针部分以获得启发。

于 2013-02-05T06:18:39.280 回答
0
  1. 当您使用 /WALL 运行程序时会发生什么?吐出什么警告?为什么?
  2. 当您在附加调试器的情况下单步执行程序时会发生什么?每行的每个变量的值是多少?为什么?

您的代码有几个问题:

  1. 您不检查 malloc 的结果以查看它是否返回 NULL。

  2. 您将数组的取消引用传递给 init_array,即您将数组的第一个 int 发送给 init_array,然后立即取消引用它。由于 malloc 返回垃圾数据,因此您在 init_array 中取消引用一个随机数。

  3. array_size 不是魔术。如果您不跟踪 C 中数组的大小,则无法追溯找出您希望它们有多大。您需要记住数组的大小并将其传递给 init_array。

于 2013-02-05T06:25:29.343 回答