-1

main() からこの関数を呼び出すまで、私の C プログラムはコンパイルされ、正常に動作します。

void rearrangeMainDiagonal(int mat[MAX_ORDER][MAX_ORDER], int order)
{
    int i, j, k=0, l=0, n=0;
    int temp[20], odd_temp[20], even_temp[20];

    for(i=0;i<order;i++) 
    {
        for(j=0;j<order;j++)
        {
            temp[k] = mat[i][i];
            k++;
        }
    }

    for(i=0;i<=k;i++)
    {
        if(temp[i]%2==0)
        {
            even_temp[l] = temp[i];
            l++;
        }
        else
        {
            odd_temp[n] = temp[i];
            n++;
        }
    }

    for(j=0;j<=n;j++)
    {
        temp[j] = odd_temp[j];
    }

    for(i=0;i<=l;i++,j++)
    {
        temp[j] = even_temp[i];
    }

    k=0;
    for(i=0;i<order;i++)
    {
        for(j=0;j<order;j++)
        {
            mat[i][i] = temp[k] ;
            k++;
        }
    }
}

プログラムを実行すると、「プログラムは動作を停止しました。プログラムを閉じてください。ステップごとに実行しようとすると、「プログラムでアクセス違反が発生しました」と表示されて停止します。行「temp[j] = odd_temp[j];」を含む「for ループ」でエラーがポップアップします。

4

1 に答える 1

2

プログラムがそのプログラムに割り当てられていないメモリにアクセスしようとすると、セグメンテーション違反が発生します。

セグメンテーション違反の最も一般的な理由 (NULL ポインターの逆参照を除く) は、その境界を超えて配列にアクセスすることです。

例:

int arr[5];
for (int i=0; i<=5; i++)
    arr[i]=i;

arr存在しない5 番目の要素にアクセスすると、セグメンテーション違反がスローされます(したがって、割り当てられていないその背後のメモリにアクセスしようとします。

プログラムには、これが発生する可能性のある場所が複数あります。

void rearrangeMainDiagonal(int mat[MAX_ORDER][MAX_ORDER], int order)
{
    int i, j, k=0, l=0, n=0;

固定サイズの配列を作成しますが、それらを使用するときにインデックスを確認することはありません。他のすべての調整が正しい場合は、次を使用することをお勧めします。

    int temp[MAX_ORDER], odd_temp[MAX_ORDER], even_temp[MAX_ORDER];

順序を MAX_ORDER 以下にする:

    assert(order <= MAX_ORDER);

関数名に基づいて、私はこれを疑っています

    for(i=0;i<order;i++) 
    {
        for(j=0;j<order;j++)
        {
            temp[k] = mat[i][i];
            k++;
        }
    }

サイズtempが必要です。order*order

もっと似てるはず

    for(i=0;i<order;i++) 
    {
        temp[i] = mat[i][i];
    }

したがって、すべての要素を主対角線上にtemp配列内に 1 回配置orderします。

kここでは、割り当て後に k をインクリメントしたため、上記のループのバージョンでは設定しなかった 'th 要素まで temp をループしk-1ます。i<ki<=k

    for(i=0;i<=k;i++)

(上記のループの変更後)になる必要があります。

    for(i=0;i<order;i++)
    {
        if(temp[i]%2==0)
        {
            even_temp[l] = temp[i];
            l++;
        }
        else
        {
            odd_temp[n] = temp[i];
            n++;
        }
    }

n' 番目の要素がodd_temp設定されていません。j<n

    for(j=0;j<n;j++)
    {
        temp[j] = odd_temp[j];
    }

l' 番目の要素がeven_temp設定されていません。i<l

    for(i=0;i<l;i++,j++)
    {
        temp[j] = even_temp[i];
    }

ここで、最初のループと同じミスが発生します。これは次のようになります。

    for(i=0;i<order;i++)
    {
        mat[i][i] = temp[i];
    }
}

変数 k は使用されていないため、削除することもできます。関数がまだやりたいことを実行している場合は、次の順序で行列を処理できるはずです。MAX_ORDER

于 2013-03-28T14:27:25.757 に答える