繁体   English   中英

将值分配给在结构中启动的二维数组会导致无限循环

[英]Assigning values to a 2d array initiated in a struct causes an infinite loop

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

我正在尝试运行上面的代码,并将值分配给在struct中初始化的2d数组(大写字母均为#define值)。 由于某种原因,我不断进入日食的无限循环。 生成项目时(运行时)不会引发任何标志。 谁能告诉我我在做什么错?

谢谢!

声明Game *thegame = (Game *)malloc(sizeof(Game*))肯定是错误的; 连同thegame->gameBoard[row][col] = EMPTY_ENTRY ,当您访问未分配的内存时,它会引入未定义的行为。 因此,您应该Game *thegame = malloc(sizeof(Game))编写Game *thegame = malloc(sizeof(Game)) 请注意,在C语言中,最好不要这里讨论的那样强制转换malloc的结果。

无论如何,如果将EMPTY_ENTRY定义为值0 ,则您也可以使用calloc ,它将初始化内存为0 因此,您可以省略for -loops(参见cppreference / calloc ):

void* calloc( size_t num, size_t size ); 分配内存阵列num大小的对象size和初始化在该分配的存储到零所有的字节。

该功能有两个问题。

首先这句话

Game *thegame = (Game *)malloc(sizeof(Game*));

分配大小等于指针Game*的大小的内存,而不是分配大小等于结构Gamestruct game_t相同的大小的内存。

你必须写

Game *thegame = (Game *)malloc(sizeof(Game));

要么

Game *thegame = (Game *)malloc(sizeof(struct game_t));

第二个问题是,当变量historySize小于或等于0时,可能会发生内存泄漏。

考虑到最好将function参数指定为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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM