0

進行中に複数の変数、特に最後の 3 つの引数を変更する必要がある関数を C で作成しています。関数宣言を以下に示します。

void Sample_v2(double cyl_radius, double thetaOx, double binsize, double ** newRx, double * binCenterThetas, double ** binCenters) 

そして、私の変数は次のとおりです。

int main() {
    // initialize function outputs
    double ** GPU_binCenters;
    double ** GPU_Rx;
    double * GPU_binCenterThetas;
    // set testing values
    double cyl_rad = 0.3;
    double theta = 1.5708;
    double binsiz = 0.0025;
    int n;

    Sample_v2(cyl_rad, theta, binsiz, GPU_Rx, GPU_binCenterThetas, GPU_binCenters);

    fprintf(stdout,"GPU_binCenters\n");
    for (n = 0; n < 188; n++) {
        fprintf(stdout, "%G\n", GPU_binCenterThetas[n]);
    }
}

次のコードで配列の値を指定します。

newRx = (double**) calloc((int)ceil(howmany) * 2, sizeof(double*));
for (ii = 0; ii < (int)ceil(howmany) * 2; ii++) {
    newRx[ii] = (double*) calloc(2, sizeof(double));
}

また

binCenterThetas = (double*) calloc((int)ceil(howmany)*2+1, sizeof(double));

初めて実行するときに、for ループの fprintf ステートメントでこれを実行しようとすると、segfault が発生します。gdb を使用すると、手動で値を読み取ることもできませんが、ポインター アドレスは表示されます。ポインターを渡すときにポインターがコピーされていると思いますが、参照によって変更する必要がある変数を渡す別のソリューションを実装しようとしましたが、それにも問題がありました。そのためのコードは次のとおりです。

Sample_v2(cyl_rad, theta, binsiz, &GPU_Rx, &GPU_binCenterThetas, &GPU_binCenters);

    ...........

void Sample_v2(double cyl_radius, double thetaOx, double binsize, double *** newRx, double ** binCenterThetas, double *** binCenters) {

    ...........

*newRx = (double**) malloc((int)ceil(howmany) * 2 * sizeof(double*));
for (ii = 0; ii < (int)ceil(howmany) * 2; ii++) {
    *newRx[ii] = (double*) malloc(2 * sizeof(double));
}

そのコードは、for ループ内でメモリを割り当てるときにセグメンテーション違反を起こします。セグメンテーション違反なしで実際に配列を渡すか初期化する方法についてのヘルプ。関数内で変更される 3 つの配列があるため、return ステートメントを使用していないことに注意してください。

4

1 に答える 1

2

電話すると

Sample_v2(cyl_rad, theta, binsiz, GPU_Rx, GPU_binCenterThetas, GPU_binCenters);

が受け取る引数はSample_v2のポインタのコピーであり、 でこれらのポインタmainに加えられた変更Sample_v2は のポインタに影響を与えないため、ループにmain入るとき、はまだ初期化されていないポインタであり、アクセスは未定義の動作であり、セグメンテーション違反。fprintfGPU_binCenterThetasGPU_binCenterThetas[n]

実際にこれを処理する正しい方法は、間接レイヤーを追加してこれらのポインターのアドレスを渡すことです (またはstruct、適切な型の 3 つのポインターを含む を定義してそれを返します。変更するポインターが 1 つしかない場合は、ポインターを返すことになります。私の好みの方法 - ポインターが返された場合、それらを引数として渡す必要はありません)。

あなたの試みの問題

Sample_v2(cyl_rad, theta, binsiz, &GPU_Rx, &GPU_binCenterThetas, &GPU_binCenters);

    ...........

void Sample_v2(double cyl_radius, double thetaOx, double binsize, double *** newRx, double ** binCenterThetas, double *** binCenters) {

    ...........

*newRx = (double**) malloc((int)ceil(howmany) * 2 * sizeof(double*));
for (ii = 0; ii < (int)ceil(howmany) * 2; ii++) {
    *newRx[ii] = (double*) malloc(2 * sizeof(double));
}

優先順位を間違えているということです。

*newRx[ii]

*(newRx[ii])

newRx[ii]の有効なポインターにすぎませんii == 0。あなたが意味したのは

(*newRx)[ii]

(および他のものについても同様)。

于 2013-02-13T18:58:50.567 に答える