1

gslランダムジェネレーターを使用して2つの大きな行列を生成し、gsl cblasを使用してそれらを乗算しますが、cblas操作の開始時に常にセグメンテーション違反が発生しました。これを解決できない場合は、行列の乗算を行うための非常に基本的なアイデアを使用して、以下のコードを記述します。それでもセグメンテーション違反が発生しますが、行列が本当に小さい場合は、2つすべてが正常に機能します。 mはこれについて本当に戸惑いました。

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define PI 3.1415926

void GenerateKey(int m, int n, int l, int q, float alpha)
{
    // initialization
    int i;
    int j;
    int k;

    float *A;
    float *S;
    float *E;
    float *B;

    float sigma = (alpha * q ) / sqrt(2 * PI);
    A=(float*)malloc(sizeof(float)*(m*n));
    S=(float*)malloc(sizeof(float)*(n*l));
    B=(float*)malloc(sizeof(float)*(m*l));
    E=(float*)malloc(sizeof(float)*(m*l));

    // init A
    for(i = 0; i < m*n; i++)
    {
        A[i]=0;
    }
    printf("\n");

    // init S
    for(i = 0; i < n*l; i++)
    {
        S[i]=0;
    }

    printf("\n");

    // init E
    for(i = 0; i < m*l; i++)
    {
        E[i]=0;
    }

    printf("\n");
    float po;
    for(i = 0; i < m; i++)
    {
        for(j=0; j<l; j++)
        {      
            po=0;
            for(k=0; k<n; k++)
            {
                po +=A[i*m+k]*S[k*n+j];
            }
            po += E[i*m +j];
            B[i*m+j]=((int)po) % q;
        }
    }

    printf("Game over");

    printf("\n");
    free(A);
    free(B);
    free(S);
    free(E);
}

int main()
{
    GenerateKey(2680,191,64,72973,0.000551);

    return 0;
}
4

3 に答える 3

3

あなたがしているとき、それはそうi*m+jではありませんi*l+jか?同様にi*m+kあるべきでi*l+kあり、k*n+jあるべきであるk*l+j

その理由は、たとえばE = (float*)malloc(sizeof(float)*(m*l))m行とl列がある(またはその逆)ため、ディメンションを反復処理する場合は、イテレータ(この場合)にそのディメンションの行列のストライドをm乗算する必要があります。これはです。mil

于 2012-10-22T13:35:33.437 に答える
1

戻り値をチェックしないmalloc()ので、1つ以上の割り当てが失敗し、間接参照していると思いますNULL。もう1つの可能性は、もちろんインデックスエラーであるため、範囲外でアクセスします。

于 2012-10-22T13:30:57.897 に答える
1

すべての行列の要素インデックスを誤って計算しました。

MxN1次元配列として割り当てられた行列がある場合、要素のインデックス(i,j)はですi*N+j。代わりに、として計算していi*M+jます。

于 2012-10-22T13:37:29.460 に答える