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

void setZero (double **, int);

int main (void) {
        double *ptr = NULL;
        int i, size = 3;
        ptr = (double *)malloc(size * sizeof(double));
//*
        setZero(&ptr, size);
/*/
        // Sanity test
        for ( i = 0 ; i < size ; ++i ) {
                printf("index %d/%d\n", i, (size-1));
                ptr[i] = 0;  // NOT EXPLODING...
        }
//*/
        free(ptr);
        return 0;
}

void setZero (double **_ref_array, int _size) {
    int i;

    for ( i = 0 ; i < _size; ++i ) {
        printf("index %d/%d\n", i, (_size-1));
        *_ref_array[i] = 0;  // EXPLODING...
    }
}

1)なぜこれが機能しないのですか?

2)「バスエラー10」とは

PS私はこの方法で配列を初期化するよりもよく知っていますが、これは私が理解していない基本的な概念の単純でクリーンな例です...

4

2 に答える 2

3

インデックスの後に間接参照が発生しています。つまり

これは、「インデックス'i'でダブルポインタを取得し、そのポインタ内のアドレスのメモリに値0を設定する」ことを示しています。

*_ref_array[i] = 0; 

これは、「i-doublesでそのアドレスにインデックスを付けるよりも、_ref_arrayからdoubleの配列のアドレスを取得する」という意味です。

(*_ref_array)[i] = 0;
于 2012-11-06T02:48:32.893 に答える
2

与えられたコードの表面では、ポインタのアドレスを関数に渡す必要はありません。次のものを使用する必要があります。

void setZero(double *ptr, int size)
{
    for (int i = 0; i < size; i++)
        ptr[i] = 0.0;
}

と:

setZero(ptr, size);

あなたが抱えている問題は、WhozCraigが言うようにです:

*_array_ref[i]

次のように解釈されます:

*(_array_ref[i])

それ以外の:

(*_array_ref)[i]

必要に応じて。前者はスタックを踏みにじっています。後者は、割り当てられたメモリを初期化しています。

関数へのポインターへのポインターを本当に渡す必要がある場合は、間接参照を括弧で囲むか、ローカルポインターを割り当てて、doubleを使用する必要があるポイントまで通常どおりに使用できます。呼び出し元の関数の値を変更するためのポインター。

void setZero(double **ptr, int size)
{
    double *base = *ptr;
    for (int i = 0; i < size; i++)
    {
        base[i] = 0.0;
        // Or: (*ptr)[i] = 0.0;
    }
    ...presumably some code here needs to assign to *ptr...
    ...if there is no such code, there is no need of the double pointer...
}
于 2012-11-06T02:56:40.453 に答える