1
#include <stdio.h>
#include <conio.h>

#define     GRID_X              30
#define     GRID_Y              20

unsigned char board[GRID_Y][GRID_X];

void draw_board( unsigned char ** );
void print_board( unsigned char ** );

int main()
{
    draw_board( board );
    getch();
    return 0;
}

void draw_board( unsigned char **board )
{

    unsigned int  r_itr = 0,
                  c_itr = 0;

    if( NULL == board )
    {
        printf( "cannot create board..!!" );
        exit(0);
    }

    r_itr = 0;

    for( c_itr = 0; c_itr < GRID_X; ++c_itr )
    {
        board[ r_itr ][ c_itr ] = '+'; /* <- crashing here  */
        board[ r_itr + ( GRID_Y-1 ) ][ c_itr ] = '+';
    }

    c_itr = 0;

    for( r_itr = 0; r_itr < GRID_Y; ++r_itr )
    {
        board[r_itr][c_itr] = '+';
        board[ r_itr ][ c_itr + GRID_X-1 ] = '+';
    }

    print_board( board );
 }

void print_board( unsigned char **board )
{
    int r = 0,
        c = 0;

    for( r = 0; r < GRID_Y; ++r )
    {
        for( c = 0; c < GRID_X; ++c )
        {
            printf( "%c", board[r][c] );
        }

        printf("\n");
    }
}

The above code is crashing at the point I mentioned via comment ( crashing here ). I did all the possible boundary-checking ( based on my understanding ), I am still not able to detect the reason for crashing? I used GNU GCC compiler and code blocks IDE.please help?

4
  • 3
    The data type of your function parameter is wrong. board is not a unsigned char **; its an array of arrays. They are NOT synonymous. Commented Sep 13, 2014 at 3:27
  • 2
    Why are you passing board to all your functions as argument, when it is a global variable? Commented Sep 13, 2014 at 3:28
  • i know its weird but its actually not a global i made it to express my doubt in a simple manner. Commented Sep 13, 2014 at 3:31
  • 1
    So many C beginners think an array will decay to a pointer when they pass it, but it decays only once, so a 2D array wouldn't decay to a pointer to pointer. Commented Sep 13, 2014 at 3:38

2 Answers 2

2

You should use:

void draw_board( unsigned char board[][GRID_X] )

or

void draw_board( unsigned char (*board)[GRID_X] )

Update

Why does the function draw_board, as defined in the question, cause problems?

Let's say you have

char b[2][3] = {{0}, {0}};

The layout of memory for the array is:

<--- b[0]     --->|<--- b[1]     --->

a1    a2    a3    a4    a5    a6
+-----+-----+-----+-----+-----+-----+
| 0   | 0   | 0   | 0   | 0   | 0   |
+-----+-----+-----+-----+-----+-----+

where a1 ... a6 are addresses.

When you pass b to a function, it decays to a pointer and the value passed to the function is a1.

Let's say you have a function foo declared as:

void foo(char** b);

When you pass the b to foo, the value of b in foo is a1.

b[0] = *b = *a1

The data being held at address a1 is now being treated as a char*. If the size of a pointer is 4 bytes,

b[0] = 0;

If you dereference b[0], such as in an expression b[0][0], you will get undefined behavior.

Sign up to request clarification or add additional context in comments.

3 Comments

ok i see data type mismatch is there. but how it leads to crashing?
@user2070804 because its wrong. you're using the wrong pointer type and thus have an invalid alias, Therefore your program invokes undefined behavior when using that pointer. Thus the program is ill-formed and may crash.(and in this case, is highly likely to do just that). +1, btw, on the answer
ill-formed and may crash.ok i got you.still didnt explain why its crash. the statement "board[r_itr][c_itr]" will alwats read one byte right?
0

The problem is that for 2-d matrices, the expressions unsigned char[][] and unsigned char ** are not compatible. The C language FAQ and this other question will explain the differences.

When you compiled your code, you should have seen a warning like the following. This is from gcc:

warning: passing argument 1 of 'draw_board' from incompatible pointer type

If you want to fix the problem and keep draw_board() the same, you need to declare board as unsigned char ** and allocate memory like so:

#include <stdio.h>
#include <stdlib.h>
//#include <conio.h>

#define     GRID_X              30
#define     GRID_Y              20

//unsigned char board[GRID_Y][GRID_X];
unsigned char **board;

void draw_board( unsigned char ** );
void print_board( unsigned char ** );

int main()
{
    board = (unsigned char **) malloc(sizeof(unsigned char *) * GRID_X);
    int i;
    for (i = 0; i < GRID_X; i++)
    {
        board[i] = (unsigned char *) malloc(sizeof(unsigned char) * GRID_Y);
    }

    draw_board( board );
    //getch();
    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.