总而言之,我在棋盘程序中收到了一些有趣的错误。我运行 Valgrind~$ valgrind --track-origins=yes ./a.out
并得到了一些我难以解释的错误报告。
==10171== Conditional jump or move depends on uninitialised value(s)
==10171== at 0x80488C2: diagnols.2353 (eq1.c:95)
==10171== by 0x8048942: check.2372 (eq1.c:109)
==10171== by 0x80485E6: recur (eq1.c:118)
==10171== by 0x804872B: recur (eq1.c:151)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x8048618: recur (eq1.c:123)
==10171== Uninitialised value was created by a heap allocation
==10171== at 0x402BB7A: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10171== by 0x804897A: main (eq1.c:159)
以下是代码中的一些实例:
重复,第 123 行:
if ( (result == 2)/*&&(width!=7)*/ ) { // go to next row, try first column puts("Option 1\n"); recur(key, (depth + 1), 0); // line 123 }
重复,第 141 行:
else if ( (result != 2)&&(width<7) ) { // didn't work, try next column // go to next column, same row puts("Option 3\n"); key->board[depth][width] = 0; recur(key, depth, (width+1)); // line 141
诊断,第 95 行:
while ( ((abc>=0)&&(bcd>=0) && (abc<=7)&&(bcd<=7)) ) { if (key->board[abc][bcd] == 1) { counter++; }
完整的诊断功能:
int diagnols(int PARAMETER_ONE, int PARAMETER_TWO) { // returns 0 if good
int abc = 0;
int bcd = 0;
int counter = 0;
// first check diagnol up and to the left
abc = PARAMETER_ONE-1;
bcd = PARAMETER_TWO-1;
while ( bcd>=0 && abc>=0 && abc<=7 && bcd<=7 ) {
if (key->board[abc][bcd] == 1) {
counter++;
} abc--;
bcd--;
}
// checking diagnol up and to the right
abc = PARAMETER_ONE-1;
bcd = PARAMETER_TWO+1;
while ( abc>=0 && bcd>=0 && abc<=7 && bcd<=7 ) {
if (key->board[abc][bcd] == 1) {
counter++;
} abc--;
bcd++;
}
// checkign diagnol down and to the left
abc = PARAMETER_ONE+1;
bcd = PARAMETER_TWO-1;
while ( abc>=0 && bcd>=0 && abc<=7 && bcd<=7 ) {
if (key->board[abc][bcd] == 1) {
counter++;
} abc++;
bcd--;
}
// checking diagnol down and to the right
abc = PARAMETER_ONE+1;
bcd = PARAMETER_TWO+1;
while ( abc>=0 && bcd>=0 && abc<=7 && bcd<=7 ) {
if (key->board[abc][bcd] == 1) {
counter++;
} abc++;
bcd++;
}
return counter;
}
起源追踪:
int main() {
struct chessboard* master = malloc(sizeof(struct chessboard));
/* zero out board */
int one = 0;
int two = 0;
for (one; one <= 7; one++) {
for (two; two <= 7; two++) {
master->board[one][two] = 0;
}
}
结构是:
struct chessboard {
int board[8][8]; // corrected
};
第二组错误
==10171== Invalid read of size 4
==10171== at 0x8048767: vertical.2344 (eq1.c:51)
==10171== by 0x804892B: check.2372 (eq1.c:108)
==10171== by 0x80485E6: recur (eq1.c:118)
==10171== by 0x804872B: recur (eq1.c:151)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x804868C: recur (eq1.c:141)
==10171== by 0x8048618: recur (eq1.c:123)
==10171== Address 0x41f8128 is 0 bytes after a block of size 256 alloc'd
==10171== at 0x402BB7A: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10171== by 0x804897A: main (eq1.c:159)
显然,出现了很多相同的行。
垂直功能:
int vertical(int PARAMETER) { // param = 2nd val in 2D || returns 1 if good int ab = 0; int counter = 0; for (ab; ab <= 7; ab++) { if ( (key->board[ab][PARAMETER] == 1) ) { counter++; } } return counter; // if one, it is okay; if > 1, not okay }
我不确定问题是什么。它似乎不喜欢我的malloc
,但我立即初始化它。我试过改变数组大小,改变循环边界,calloc()
而不是malloc()
等等。任何帮助表示赞赏!
整个程序:
#include <stdio.h>
#include <stdlib.h>
struct chessboard {
int board[8][8];
};
void print_board(struct chessboard* key) {
for(int a = 0; a <= 7; a++) {
for(int b = 0; b <= 7; b++) {
if (key->board[a][b]==0) {
printf("[x]");
} else {
printf(" q ");
}
}
printf("\n");
}
puts("\n");
}
int recur(struct chessboard* key, int DEPTH, int WIDTH) {
int depth = DEPTH;
int width = WIDTH;
/* set a piece as a queen */
key->board[depth][width] = 1;
/* check for conflicts */
int horizontal(int column) { // param = first val in 2D || returns 1 if good
int a = 0;
int counter = 0;
for(;a <= 7; a++) {
if ( key->board[column][a] == 1 ) {
counter++;
}
}
return counter; // if one, it it is okay; if > 1, not okay
}
int vertical(int row) { // param = 2nd val in 2D || returns 1 if good
int ab = 0;
int counter = 0;
for(;ab <= 7; ab++) {
if ( (key->board[ab][row] == 1) ) {
counter++;
}
}
return counter; // if one, it is okay; if > 1, not okay
}
int diagnols(int column, int row) { // returns 0 if good
int counter = 0;
// first check diagnol up and to the left
int abc = column-1;
int bcd = row-1;
while ( bcd>=0 && abc>=0 && abc<=7 && bcd<=7 ) {
if (key->board[abc][bcd] == 1) {
counter++;
} abc--;
bcd--;
}
// checking diagnol up and to the right
abc = column-1;
bcd = row+1;
while ( abc>=0 && bcd>=0 && abc<=7 && bcd<=7 ) {
if (key->board[abc][bcd] == 1) {
counter++;
}
abc--;
bcd++;
}
// checkign diagnol down and to the left
abc = column+1;
bcd = row-1;
while ( (abc>=0)&&(bcd>=0) && (abc<=7)&&(bcd<=7) ) {
if (key->board[abc][bcd] == 1) {
counter++;
}
abc++;
bcd--;
}
// checking diagnol down and to the right
abc = column+1;
bcd = row+1;
while ( abc>=0 && bcd>=0 && abc<=7 && bcd<=7 ) {
if (key->board[abc][bcd] == 1) {
counter++;
}
abc++;
bcd++;
}
return counter;
}
int check(int param1, int param2) { // if okay returns 2
int h = horizontal(param1);
int v = vertical(param2);
int d = diagnols(param1, param2);
int total = 0;
total = (h + v + d); // if okay, equals 2
return total;
}
print_board(key); // shows process, can be annoying
/* choose what to do next
* option puts() statements are there for debugging
*/
int result = check(depth,width);
if ( result == 2 && depth != 7 ) { // worked, go deeper
// go to next row, try first column
puts("Option 1\n");
recur(key, (depth + 1), 0);
}
else if ( result == 2 && depth==7 ) { // done
puts("Option 2\n");
return 1;
}
else if ( result != 2 && width<7 ) { // didn't work, try next column
// go to next column, same row
puts("Option 3\n");
key->board[depth][width] = 0;
recur(key, depth, (width+1));
}
else if ( result !=2 && width == 7 ) { // didn't work AND no more column space
puts("Option 1\n");
key->board[depth][width] = 0; // set this queen to zero
for (int e = 0;e<=7;e++){ // find queen in previous row, set it to zero and recur
if (key->board[(depth-1)][e] == 1) {
key->board[(depth-1)][e] = 0;
recur(key, (depth-1), (e+1)); // could go out of bounds
}
}
}
return 0;
}
int main() {
struct chessboard* master = malloc(sizeof(struct chessboard));
/* zero out board */
for(int one = 0; one <= 7; one++) {
for(int two = 0; two <= 7; two++) {
master->board[one][two] = 0;
}
}
/* run */
int result = 0;
result = recur(master, 0, 0);
/* finish */
printf("Result was: %i\n", result);
free(master);
return 0;
}