それがあなたの観察の原因であるかどうかはわかりませんが、334行目以降で、
char mirrored[BOARD_WIDTH][BOARD_HEIGHT];
for (int x = 0; x<BOARD_WIDTH; x++) {
for (int y=0; y<BOARD_HEIGHT; y++) {
mirrored[x+1-BOARD_WIDTH][y] = board[x][y];
}
}
割り当てられたメモリの外側に書き込みます(行インデックスは から-(BOARD_WIDTH)
になります-1
)。したがって、未定義の動作が呼び出されます。
また、それはボードを反映していません。あなたはおそらく意味した
mirrored[BOARD_WIDTH - 1 - x][y] = board[x][y];
そこの。それとは別に、境界外書き込みのような明白な候補は見当たりません。
(行 43ff)ではisBoardFinished
、行/列 0 に到達する前にチェックを停止します。
while (xTemp > 0)
(y
トップダウンチェック、および対角線チェックの両方についても同様です)。それはx >= 0
フルボードを使用することです。しかし、これは を上書きできませんでしalreadyCounter
たが、それでも役に立つかもしれません。
しかし、警告をオンにして最適化を行ってコードをコンパイルすると、考えられる原因が示されます。
connect-four.c: In function ‘getFirstIndex’:
connect-four.c:202:19: warning: ‘index’ may be used uninitialized in this function [-Wuninitialized]
connect-four.c: In function ‘getNewIndex’:
connect-four.c:202:19: warning: ‘index’ may be used uninitialized in this function [-Wuninitialized]
connect-four.c:199:18: note: ‘index’ was declared here
connect-four.c: In function ‘getMyIndex’:
connect-four.c:202:19: warning: ‘index’ may be used uninitialized in this function [-Wuninitialized]
connect-four.c:199:18: note: ‘index’ was declared here
connect-four.c: In function ‘makeTurns’:
connect-four.c:202:19: warning: ‘index’ may be used uninitialized in this function [-Wuninitialized]
connect-four.c:199:18: note: ‘index’ was declared here
connect-four.c:202:19: warning: ‘index’ may be used uninitialized in this function [-Wuninitialized]
connect-four.c:199:18: note: ‘index’ was declared here
したがって、警告と付随する注記 (関数名は異なりますが、インライン化のために同じ場所で複数回表示されます) は、次のようにする必要があることを示しています。
unsigned int getFirstIndex(char board[BOARD_WIDTH][BOARD_HEIGHT]) {
unsigned int index = 0;
// ^^^^^^^
getFirstIndex
同一のボードで呼び出して決定論的な結果を得る。ただし、インデックスを返す前にモジュラスを取得するためMAXIMUM_SITUATIONS
、返されるインデックスが範囲外であってはなりません。したがって、その結果としてクラッシュは予想されません。しかし、何かを印刷すると、スタックに割り当てが発生する可能性があります (必要ではなく、引数と戻りアドレスはすべてレジスタに渡される可能性があります)。index
次回getFirstIndex
が呼び出されます。それは返される値を変更し、 の間違ったスロットを調べるdatabase
ため、同じボードの以前の出現を見逃すため、値getFirstIndex
が生成するだけの場合よりも重複が少なくなります。渡されたボードに依存します (また、特定のスタック位置を占めるビットにも依存しません)。
私のバージョンのgccでは、警告を取得するには、警告をオンにして最適化する必要があることに注意してください。警告clang
と最適化を最高レベルにしても警告しません。他のバージョンの gcc と clang、および他のコンパイラーでは、問題の特定が異なる場合があります。
index
で 0 に初期化すると、getFirstIndex
一貫した結果が得られます
########################Finish:
Maximum of 20000 reached
alreadyCounter: 4412
文字列が出力されるかどうか、および最適化レベルとは無関係です。初期化しないと、 の値はalreadyCounter
両方の要因に依存します。