2

在这个程序中有一行我创建了一个名为“crazy_integer”的变量。

如果我不创建这个变量,MinGW 会创建一个无限循环!我似乎对任何其他编译器都没有这个问题。

谁能告诉我这里发生了什么?

重新创建:使用 MingW 下载最新版本的 CodeBlocks,创建一个新的控制台项目,然后尝试运行该程序。

然后,尝试删除我创建“crazy_integer”的代码行并再次运行该程序。结果应该是一个无限循环。

// In this program there is a line where I create a variable called 
// "crazy_integer". 
//
// If I do not create this variable, CodeBlocks creates an infinite loop!
// I do not seem to have this problem with any other compiler.
//
// Can anyone tell me what is going on here? 
//
// To recreate: Download the latest version of CodeBlocks with MingW, create
// a new console project, and try running this program.
//
// Then, try removing the line of code where I create "crazy_integer" 
// and run the program again. The result should be an infinite loop.

#include <stdio.h>
#include <string.h>

int find_winning_move(char *, char, int);
int display_board(char *);
int is_winning_position(char *, char);
void show_win_details(int, char);

int main(void) {
    int retval = 0;
    char raw_data[]         = "X  X XO  ";
    char player = 'X';

    printf("We are examining this board:  \n");
    display_board(raw_data);

    find_winning_move(raw_data, player, 1);

    return 0;
}

int find_winning_move(char *raw_data, char player, int depth) {

    char test_position[9];
    int crazy_integer=0;    // Adding this line will fix an infinite loop
    int i, win_result;

    for (i = 0; i < 9; i++) {
        if (raw_data[i] == ' ') {
            strcpy(test_position, raw_data);
            test_position[i] = player;
            win_result = is_winning_position(test_position, player);
            printf("The result of playing %c at position %d is: %d  \n",
                player, i, win_result);

            display_board(test_position);
        }
    }

    return 0;
}

int display_board(char *raw_data) {
    char display_model[]     = "[ ][ ][ ]\n[ ][ ][ ]\n[ ][ ][ ]\n";

    int i, j, k; k=0;

    for (i = 0; i <= 2; i++) {
        for (j = 1; j <= 7; j+=3) {
            display_model[ (i * 10) + j ] = raw_data[k++];
        }
    }

    printf("%s ", display_model);
}

int is_winning_position(char *raw_data, char player) {

    int i;

    // Test for horizontal win
    for (i = 0; i <= 6; i+=3) {
        if (raw_data[i] == player
            && raw_data[i+1] == player
            && raw_data[i+2] == player)
        {
            return 10 + i;
        }
    }

    // Test for vertical win
    for (i = 0; i <= 2; i++) {
        if (raw_data[i] == player
            && raw_data[i+3] == player
            && raw_data[i+6] == player)
        {
             return 20 + i;
        }
    }

    // Test for diagonal win
    if (raw_data[4] == player) {
        if (raw_data[0] == player && raw_data[8] == player) {
            return 31;
        }
        if (raw_data[2] == player && raw_data[6] == player) {
            return 32;
        }
    }

    return 0;

}

void show_win_details(int win_value, char player) {

    switch (win_value) {

        // Horizontal
        case 10 :
            printf("Horizontal win on first row for Player: %c  \n",
                player);
        break;
        case 13 :
            printf("Horizontal win on second row for Player: %c  \n",
                player);
        break;
        case 16 :
            printf("Horizontal win on third row for Player: %c  \n",
                player);
        break;

        // Vertical
        case 20 :
            printf("Vertical win on first column for Player: %c  \n",
                player);
        break;
        case 21 :
            printf("Vertical win on second column for Player: %c  \n",
                player);
        break;
        case 22 :
            printf("Vertical win on third column for Player: %c  \n",
                player);
        break;

        // Diagonal
        case 31 :
            printf("Diagonal win upper left to lower right for Player: %c  \n",
                player);
        break;
        case 32 :
            printf("Diagonal win lower left to upper right for Player: %c  \n",
                player);
        break;

        default: printf("Some error occurred.  \n"); break;

    }
}
4

1 回答 1

4

你的变量声明:

char test_position[9];

太短了strcpyin it ( strcpy(test_position, raw_data);)。源缓冲区raw_data是 9 个字符加上空终止符。所以它会导致缓冲区溢出。添加该整数变量可能会在堆栈上提供额外的空间,以“修复”堆栈溢出。

于 2012-07-23T23:53:16.637 回答