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 FAQの配列とポインターのセクションを読む必要があります。

于 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 に答える