Intent Filters Intent Filters - 3 months ago 8
C Question

Weird bug where value of multidimensional array is "skipped"

Im trying to implement a function that searches a multidimensional array finds out if a value is in it, then moving that function. My search function

bool search(int value, int values [][d], int n)
{
bool In = false;
//d is an it that is the maximum length and height
//e.g 3x3 or 4x4 as in the image below

for(int row=0; row<d; row++)
{
for(int col=0; col<d; col++)
{
if(values[row][col] == value)
{
//checking if this loop is executed
printf("EXECUTED!! :) \n");
In=true;
}
printf("Row:%i & Col%i: %i \n",row,col,values[row][col]);

}
}

//Usleep for debugging purpouses
// as another function clears the screen
usleep(50000000);

if(In==true){return true;}
if(In==false){return false;}


}


This is what is printed which is weird as to print the 4x4 box above i used the same array and the search function does not alter the array in anyway.
This is my "move" function

bool move(int tile)
{

if(search(tile,board,d))
{
printf("please execute this code pretty please clang\n");
return true;
}
else
{
printf("NOO\n");
return false;
}

}


And here is the function that initilazes the variable in the first place

void init(void)
{
bool even;

if((d & 1) == 0)
{
even = true;
}
else
{
even = false;
}

int value = d*d - 1;

for(int row =0; row<d; row++)
{
for(int col=0; col<d; col++)
{
board[row][col]=value;
value--;
}
}

//for this game to work if d is even the values of the third
// and second last arrays must be switched
if(even==true)
{
int temp = board[d-1][d-2];
board [d-1][d-2] = board[d-1][d-3];
board [d-1][d-3] = temp;

}
}


EDIT: Here is the pastebin for the full code http://pastebin.com/yS8DDEqZ
Note Cs50 is a custom libary that was implemented by the class im taking, it
defines a string a helper functions which get user input GetInt() etc.

Answer

Okay, I got it.

You're defintely using a C99 compliant compiler, that allows variable length arrays.

Relevant extracts from your code:

#define MAX 9
int board[MAX][MAX]; // <- board is an int[9][9]

int d; // <- d is a global variable

bool search(
    int value,
    int values[MAX][d], // <- tells compiler to handle values as int[9][d]
    int n); 

// from within init()
for(int row =0; row<d; row++)
for(int col=0; col<d; col++)
    board[row][col]=value--; // <- board inited as an int[9][9]

A fixed size array is a big lump of contiguous memory, with rows stored one after the other.

Example:

int a[2][3] is stored as 6 ints corresponding to:

a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]

here board memory layout is 9x9 :

000000000
111111111
222222222
333333333
444444444
555555555
666666666
777777777
888888888

or in linear memory:

000000000111111111222222222333333333444444444555555555666666666777777777888888888

Now if d is 4 as your screenshot shows, the search function will think its layout is :

0000
1111
2222
3333
4444
5555
6666
7777
8888

or in linear memory:

000011112222333344445555666677778888

Your init function uses the 9x9 layout, so it puts the values like this:

15 14 13 12 x x x x x
11 10  9  8 x x x x x etc.

but your search function reads them like :

15 14 13 12
 x  x  x  x 
 x 11 10  9
 8  x  x  x 
etc.

Basically, you declared a structure for your array in the prototype of search() that is inconsistent with its declaration.

You recklessly violated one of the C little known golden rules :
always keep function parameters and array declarations consistent.
and C punished you with a cryptic bug.

Read this little essay of mine for more details.

Comments