访问2d阵列时出现分段错误?

时间:2014-09-13 03:22:21

标签: c

#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");
    }
}

上面的代码在我通过评论提到的那一点崩溃(崩溃在这里)。 我做了所有可能的边界检查(基于我的理解),我仍然无法检测崩溃的原因? 我使用GNU GCC编译器和代码块IDE.please帮助?

2 个答案:

答案 0 :(得分:2)

您应该使用:

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

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

<强>更新

为什么问题中定义的函数draw_board会导致问题?

我们说你有

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

阵列的内存布局是:

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

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

其中a1 ... a6是地址。

当您将b传递给函数时,它会衰减为指针,传递给函数的值为a1

我们假设你有一个函数foo声明为:

void foo(char** b);

当您将b传递给foo时,bfoo的值为a1

b[0] = *b = *a1

地址a1处的数据现在被视为char*。如果指针的大小是4个字节,

b[0] = 0;

如果您取消引用b[0],例如在表达式b[0][0]中,您将获得未定义的行为。

答案 1 :(得分:0)

问题是对于二维矩阵,表达式unsigned char[][]unsigned char **不兼容。 C language FAQ和此other question将解释差异。

编译代码时,您应该看到如下警告。这是来自gcc:

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

如果您想解决问题并保持draw_board()相同,则需要将board声明为unsigned char **并分配内存,如下所示:

#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;
}