简体   繁体   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;
}

I'm trying to run the code above and to assign values to the 2d array initialized in the struct (capital letters are all #define values). 我正在尝试运行上面的代码,并将值分配给在struct中初始化的2d数组(大写字母均为#define值)。 for some reason, I keep entering into an infinite loop in eclipse. 由于某种原因,我不断进入日食的无限循环。 No flag is raised when I build the project, just when I run it. 生成项目时(运行时)不会引发任何标志。 Could anyone please explain to me what am I doing wrong? 谁能告诉我我在做什么错?

thanks! 谢谢!

Statement Game *thegame = (Game *)malloc(sizeof(Game*)) is wrong for sure; 声明Game *thegame = (Game *)malloc(sizeof(Game*))肯定是错误的; together with thegame->gameBoard[row][col] = EMPTY_ENTRY , it introduces undefined behaviour, as you access memory that is not allocated. 连同thegame->gameBoard[row][col] = EMPTY_ENTRY ,当您访问未分配的内存时,它会引入未定义的行为。 So you should write Game *thegame = malloc(sizeof(Game)) instead. 因此,您应该Game *thegame = malloc(sizeof(Game))编写Game *thegame = malloc(sizeof(Game)) Note that in C, it is better not to cast the result of malloc as argued here . 请注意,在C语言中,最好不要这里讨论的那样强制转换malloc的结果。

Anyway, if EMPTY_ENTRY is defined as value 0 , you could also use calloc , which initialises the memory with 0 . 无论如何,如果将EMPTY_ENTRY定义为值0 ,则您也可以使用calloc ,它将初始化内存为0 So you could omit your for -loops then (cf. cppreference/calloc ): 因此,您可以省略for -loops(参见cppreference / calloc ):

void* calloc( size_t num, size_t size ); Allocates memory for an array of num objects of size size and initializes all bytes in the allocated storage to zero. 分配内存阵列num大小的对象size和初始化在该分配的存储到零所有的字节。

There are two problems with the function. 该功能有两个问题。

First of all this statement 首先这句话

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

allocates memory with the size equal to the size of the pointer Game* instead of allocating memory with the size equal to the size of the structure Game or struct game_t that is the same. 分配大小等于指针Game*的大小的内存,而不是分配大小等于结构Gamestruct game_t相同的大小的内存。

You have to write 你必须写

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

or 要么

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

The second problem is that there can be a memory leak in case when the variable historySize is less than or equal to 0. 第二个问题是,当变量historySize小于或等于0时,可能会发生内存泄漏。

Take into account that it is better to specify the function parameter as void . 考虑到最好将function参数指定为void

The function definition can look the following way 函数定义可以如下所示

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

Also it is not a good idea when a function deals with global variables. 函数处理全局变量时也不是一个好主意。 You could pass the variable historySize as an argument to the function. 您可以将变量historySize作为参数传递给函数。

In this case the function will look like (I suppose that the type of the variable historySize is int ) 在这种情况下,该函数将看起来像(我假设变量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;
}

In this case the function can be called like 在这种情况下,该函数可以像

Create( historySize );

There is a possibility to substitute the loops for a call of the standard function memset . 有可能用循环代替标准函数memset的调用。

For example 例如

#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