1

main() 関数から渡されたいくつかの整数ポインターを関数に取り、それらに値を割り当てようとしています。ただし、値を代入するとプログラムがクラッシュします。これが私のコードです:

int computeMoveLocation(int* r, int* c, char* board)
{
    //some code up here
    *r = 0;    //This breaks the program
    *c = 0;
}

ポインターのアドレスを変更しようとしているのではなく、指している整数の値を変更しようとしています。しかし、私は明らかに何か間違ったことをしています。

どんな助けでも大歓迎です。

編集: main() からの関連コードは次のとおりです。他にも何かを含めるべきかどうか教えてください。

int main()
{
    //initialization code
    //...

    while (1)
    {

        switch (MACHINE_STATE)
        {
            case COMPUTER_MOVE :
            {
               //check rows for three Xs
               //check columns for three Xs
               //check diagonals for three Xs
               //otherwise, move anywhere else
               int *r, *c;
               computeMoveLocation(r, c, board);
               computerMove(*r,*c, board);
               PREVIOUS_STATE = COMPUTER_MOVE;
               MACHINE_STATE = HUMAN_MOVE;
               break;
            }

            //Other cases
        }//end switch
    }//end while
}//end main
4

3 に答える 3

10

ポインタを渡していますが、メモリを割り当てていません。したがって、それらはメモリ内のランダムな場所を指しています。

int computeMoveLocation(int* r, int* c, char* board) {
    //some code up here
    *r = 0;    //This breaks the program
    *c = 0;
}

悪いメイン:

int main() {
    int *r;
    int *c;
    char *board;
    // bad, passing in pointers but didn't allocate memory
    computeMoveLocation(r, c, board); 
    return 0;
}

良いメイン#1:

int main() {
    int r = 5;
    int c = 5;
    char board = 'a';
    // fine, passing address of variables on stack
    computeMoveLocation(&r, &c, &board); 
    return 0;
}

良いメイン#2:

int main() {
    int *r = malloc(sizeof(int));
    *r = 5;
    int *c = malloc(sizeof(int));
    *c = 5;
    char *board = malloc(sizeof(char));
    *board = 'a';
    // fine, passing pointers that point to heap
    computeMoveLocation(r, c, board); 

    free(r);
    free(c)
    free(board);
    return 0;
}
于 2013-03-03T04:12:10.510 に答える
1

いつでもポインタを渡して、ポインタが指している値を変更できます。これが、ポインタの使用方法です。ただし、ポインタが実際に何かを指しているかどうかにも注意する必要があります。ポインタには、有効なアドレス、つまりその場所を変更できる値が含まれている必要があります。これを確認しないと、未定義動作が発生します。

たとえば、computeMoveLocation関数を呼び出す場合、渡すアドレスはスタックまたはヒープのいずれかである必要があります。あなたはそれを理解するために以下のコードを見ることができます。

最初の可能性

int r, c;
char board;
computeMoveLocation(&r,&c, &board);

2番目の可能性

int *r, *c;
char *board;

r = malloc(sizeof(int));
c = malloc(sizeof(int));
board = malloc(sizeof(char));
computeMoveLocation(r,c,board);

char *これは、アドレスを文字の配列に渡すためにも一般的に使用されることに注意してください。ただし、このような使用法では、通常、アドレスがnullで終了するか、付随する長さの配列も渡されるようにします。

とにかく、簡単なグーグル検索でポインタを渡すことについての詳細を得ることができます。


編集 ここで、computeMoveLocationを呼び出すコードを投稿したので、rとcをポインターとして宣言しているので、上記の2番目の可能性に従ってコードを変更するか、整数として宣言して、上記の最初の可能性。しかし、あなたは未定義の振る舞いを引き起こす同じことをしていません。

また、上記の例では、ボードにメモリを割り当てていますが、あなたの場合、それが他の場所で発生し、そこで適切に処理されていれば、マロックする必要はありません。

于 2013-03-03T04:14:21.553 に答える
1
int *r, *c;
computeMoveLocation(r, c, board);
computerMove(*r,*c, board);

ポインタを定義しますが、それが何も指さないようにします。したがって、これはワイルドまたは初期化されていないポインタです。のようにアクセスする*rcomputeMoveLocation、未定義の動作(この場合はクラッシュ)が発生します。

既知のものを指すようにポインタを初期化するか、既存のアドレスを渡す必要がありますint

int r, c;
computeMoveLocation(&r, &c, ...);

また

static int x, y; // static: only one instance of the variable exists
int *r = &x; // initialize pointers
int *c = &y;
computeMoveLocation(r, c, ...);

また

int *r = malloc(sizeof(int));
int *c = malloc(sizeof(int));
computeMoveLocation(r, c, ...);

その最後のケースでは、free後でメモリに確認してください。

于 2013-03-03T04:15:22.893 に答える