typedef struct game_t {
char gameBoard[ROWS][COLUMNS];
} Game;
Game* Create(){
Game *thegame = (Game *)malloc(sizeof(Game*));
if (thegame==NULL || historySize<=0){
return NULL;
}
int row=0, col=0;
for (row = 0; row<ROWS; row++){
for (col = 0; col<COLUMNS; col++){
thegame->gameBoard[row][col] = EMPTY_ENTRY;
}
}
return thegame;
}
我试图运行上面的代码并为结构中初始化的2d数组赋值(大写字母都是#define值)。出于某种原因,我在eclipse中不断进入无限循环。我构建项目时没有引发任何标志,就在我运行它时。 谁能请我解释一下我做错了什么?
谢谢!
答案 0 :(得分:1)
声明Game *thegame = (Game *)malloc(sizeof(Game*))
肯定是错误的;与thegame->gameBoard[row][col] = EMPTY_ENTRY
一起,当您访问未分配的内存时,它会引入未定义的行为。所以你应该写Game *thegame = malloc(sizeof(Game))
代替。请注意,在C中,最好不将malloc
的结果转换为有争议的here。
无论如何,如果将EMPTY_ENTRY
定义为值0
,您还可以使用calloc
,它会使用0
初始化内存。因此,您可以省略for
- 循环(参见cppreference/calloc):
void* calloc( size_t num, size_t size );
为数组分配内存 大小为num
的{{1}}个对象,并初始化已分配的所有字节 存储到零。
答案 1 :(得分:1)
该功能有两个问题。
首先是这句话
Game *thegame = (Game *)malloc(sizeof(Game*));
分配大小等于指针Game*
大小的内存,而不是分配大小等于结构Game
或struct game_t
大小相同的内存。
你必须写
Game *thegame = (Game *)malloc(sizeof(Game));
或
Game *thegame = (Game *)malloc(sizeof(struct game_t));
第二个问题是,如果变量historySize
小于或等于0,则可能存在内存泄漏。
考虑到最好将函数参数指定为void
。
函数定义可以采用以下方式
Game * Create( void )
{
Game *thegame = NULL;
if ( historySize > 0 && ( thegame = malloc( sizeof( Game ) ) ) != NULL )
{
for ( int row = 0; row < ROWS; row++ )
{
for ( int col = 0; col < COLUMNS; col++ )
{
thegame->gameBoard[row][col] = EMPTY_ENTRY;
}
}
}
return thegame;
}
当函数处理全局变量时也不是一个好主意。您可以将变量historySize
作为参数传递给函数。
在这种情况下,函数看起来像(我想变量historySize
的类型是int
)
Game * Create( int historySize )
{
Game *thegame = NULL;
if ( historySize > 0 && ( thegame = malloc( sizeof( Game ) ) ) != NULL )
{
for ( int row = 0; row < ROWS; row++ )
{
for ( int col = 0; col < COLUMNS; col++ )
{
thegame->gameBoard[row][col] = EMPTY_ENTRY;
}
}
}
return thegame;
}
在这种情况下,可以像
一样调用该函数Create( historySize );
有可能将循环替换为标准函数memset
的调用。
例如
#include <string.h>
//...
Game * Create( int historySize )
{
Game *thegame = NULL;
if ( historySize > 0 && ( thegame = malloc( sizeof( Game ) ) ) != NULL )
{
memset( thegame->gameBoard, EMPTY_ENTRY, ROWS * COLUMNS );
}
return thegame;
}