Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 我能';无法为此结构分配内存_C_Struct - Fatal编程技术网

C 我能';无法为此结构分配内存

C 我能';无法为此结构分配内存,c,struct,C,Struct,我有这个结构和函数: typedef struct{ char *maze_size; char *trophy; int time_max; char *moves; }gameHistory; 该函数接收指针gameHistory*gameHistoryReaded,以保留内存,但不起作用 void loadGameHistory(char fileName[], gameHistory *gameHistoryReaded, i

我有这个结构和函数:

typedef struct{

       char *maze_size;
       char *trophy;
       int time_max;
       char *moves;

}gameHistory;
该函数接收指针
gameHistory*gameHistoryReaded
,以保留内存,但不起作用

void loadGameHistory(char fileName[], gameHistory *gameHistoryReaded, int *statusCode){
       /*  Here send error  */
       *gameHistoryReaded = (gameHistory*)malloc(LENGTH_GAME_HISTORY*sizeof(gameHistory));
       (*gameHistoryReaded).maze_size = (char *)malloc(MAX_STRING*sizeof(char));
       (*gameHistoryReaded).trophy = (char *)malloc(MAX_STRING*sizeof(char));
       (*gameHistoryReaded).moves = (char *)malloc(MAX_STRING*sizeof(char));

       FILE *file = fopen(fileName,"rb");
       char line[200];
       char *token1;
       if (file == NULL){
            printf("\nError de lectura: archivo no encontrado\n");
            *statusCode = 0; //Si se presenta algun error en la lectura del archivsetea en 0 (error)
            exit(1);
        }
        fgets(line,200,file);
        token1 = strtok(line,":");
        strcpy((*gameHistoryReaded).maze_size, token1);
        token1 = strtok(NULL,":");
        strcpy((*gameHistoryReaded).trophy, token1);
        token1 = strtok(NULL,":");
        strcpy((*gameHistoryReaded).moves, token1);
        token1 = strtok(NULL,":");
        (*gameHistoryReaded).time_max = atoi(token1);

        fclose(file);

}

int main(){

        char routegameHistory[] = "game_history.txt";
        int statusCode = 1;
        gameHistory gameHistory;

        loadGameHistory(routegameHistory, &gameHistory, &statusCode);

 }
代码::Blocks向我展示了以下内容:

错误:从类型“
struct gameHistory*
”分配给类型“
gameHistory
”时,类型不兼容

但是我认为
struct
声明得很好, 另一点,,
我为
int time\u max

gameHistoryReaded
是指向
gameHistory
结构的指针

这一行:

   *gameHistoryReaded = (gameHistory*)malloc(LENGTH_GAME_HISTORY*sizeof(gameHistory));
将从
malloc()
返回的值分配给
gameHistoryReaded
指向的任何对象

可能不是你想要的


不要使用
*

取消对指针的引用,您将取消对指针gameHistoryRead的引用,这将生成结构。要将malloc的结果分配给指针本身,只需不取消引用(省略
*

为什么要将此指针传递给函数?它会立即被覆盖。如果要将malloc'ed结构返回给调用方,则需要指向该指针的指针(
**gameHistoryRead
)。在本例中,第一行是正确的,因为您正在为指针本身赋值

刚刚注意到:您已经作为结构paas了,那么为什么要malloc它呢?这毫无意义(我想现在您想要填充传递的结构,但为什么要填充malloc呢?)

只需完全删除结构的malloc(),或者查看下面的代码

然而,这是一个糟糕的设计。最好返回一个指向malloc'ed结构的指针,在出错时为NULL(参见代码blow)。请注意,调用方必须在访问返回的结构之前检查结果

此外,在错误情况下,您忘了释放()malloc'ed块。记住释放()所有分配的内存,而不仅仅是第一个结构

如果成功,您还忘记设置状态代码(如果传递要填充的结构,最好返回状态代码,而不是使用指向它的指针)

结构的malloc大小错误
sizeof(…)
已经生成了正确的大小(除非您想要返回一个数组,但是更多的都是错误的)

In main():变量的名称不能与类型的名称相同(甚至不应考虑仅更改大小写,这会妨碍可读性);请参阅main()

旁注:

  • 不要像对malloc()的结果那样强制转换
    void*
    。请参阅以获取解释
  • 使用前检查malloc的结果。它可以为空(没有可用内存)。取消对空指针的引用会导致未定义的行为(UB)。这意味着任何事情都可能发生(它甚至可以在不被注意的情况下通过)
  • 不要使用(*p).m从指针访问结构的成员。相反,请使用专门为此设计的
    ->
  • 如果其他字段(
    maze\u size
    ,…)的大小总是恒定的,为什么不简单地使用数组(具有恒定大小),避免每个字段都使用malloc?这使得清理工作更加容易
更好的办法是:

gameHistory *loadGameHistory(char fileName[])
{
    bool error = false;
    gameHistory *hist =
            malloc(sizeof(gameHistory));
    if ( hist == NULL )  return;  // fail instantly

    hist->maze_size = malloc(MAX_STRING); // sizeof(char) is 1 by standard)
    error |= hist->maze_size == NULL;

    // alloc further blocks

    // here do what you want. set error = true on error and skip rest

    // finally:
    if ( error ) {
        // out of memory: free all other blocks
        free(hist->maze_size);    // if NULL, free does nothing (standard)

        // ...

        free(hist);
        return NULL;
    }

    return hist;
}  

gameHistory游戏历史是一个错误。类型名不能重新用作变量名。假设你的意思是:

gameHistory history;
这已经分配了内存。您不需要分配任何额外内存。只需从函数中删除尝试的
malloc
行,一切都会好起来

但是,在您的函数的下面,会有一个问题:

strcpy((*gameHistoryReaded).maze_size, token1);
到目前为止,您还没有将
maze\u size
指向任何位置,因此无法将字符复制到其中。您可以将
maze\u size
设置为一个字符数组(在这种情况下,它不需要更多的分配),也可以分配空间并指向该空间:

gameHistoryReaded->maze_size = strdup(token1);
strdup
功能一次完成
malloc
strcpy


同样的问题发生在
奖杯
移动
;最后,您应该检查
token1!=每次为空。

您的建议(在第一段中)无论如何都不会起作用,因为指针是指向函数的局部变量;所以调用者看不到分配的内存(这显然是有意的)@mattmcnab:是的,我编辑了我的答案,因为我看到越来越多的问题。但是,我在第二段中提到了这一点。我最后看到的是,他实际上是在将结构传递给函数,所以完全不清楚他为什么要malloc’t这个结构。看到这样的代码,我总是有点怀旧。虽然我很高兴当时有这样的东西(或互联网)。好吧,我试着回答了,但在阅读了你的其他帖子后,我强烈建议你学习一门正确的编程/C课程(例如,读一本好书)。你应该先掌握基本知识。这也将有助于避免在每个问题上都被否决,并增加获得问题答案的机会。无意冒犯!