2014-09-13 98 views
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"); 
    } 
} 

上面的代码在我通过评论提到的点(崩溃在这里)崩溃。 我做了所有可能的边界检查(根据我的理解),我仍然无法检测到崩溃的原因? 我使用GNU GCC编译器和代码块IDE.please的帮助?访问2d数组时遇到细分?

+3

你的函数的数据类型参数是错误的。 'board'不是'unsigned char **';它是一个数组数组。它们不是同义词。 – WhozCraig 2014-09-13 03:27:05

+2

为什么要将'board'作为参数传递给所有函数?当它是全局变量时? – user1336087 2014-09-13 03:28:43

+0

我知道它很奇怪,但它其实并不是全球性的,我以简单的方式表达了我的怀疑。 – CoolToshi45 2014-09-13 03:31:20

回答

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声明如下:当您通过b为foo的bfooa1

void foo(char** b); 

。被保持在地址a1

b[0] = *b = *a1 

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

b[0] = 0; 

如果取消引用b[0],如在一个表达式b[0][0],你会得到不确定的行为。

+0

好吧,我看到数据类型不匹配。但它如何导致崩溃? – CoolToshi45 2014-09-13 03:29:28

+0

@ user2070804因为** **错误**。你正在使用错误的指针类型,因此有一个无效的别名,因此你的程序在使用该指针时会调用*未定义的行为。因此,该程序*格式不正确*和*可能*崩溃(在这种情况下,很可能会这样做)。 +1,顺便说一句,在答案 – WhozCraig 2014-09-13 03:30:57

+0

不良形成和可能crash.ok我得到了你的.still没有解释为什么它的崩溃。声明“board [r_itr] [c_itr]”将会读取一个字节吗? – CoolToshi45 2014-09-13 03:36:02

0

问题是,对于2-d矩阵,表达式unsigned char[][]unsigned char **不兼容。 C language FAQother question将解释不同之处。

当你编译你的代码时,你应该看到如下的警告。这是从GCC:

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

如果要解决这个问题,并保持draw_board()一样,你需要声明boardunsigned 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; 
}