我不能为这个结构分配内存

时间:2015-05-16 23:58:35

标签: c struct

我有这个结构和功能:

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

 }

Code :: Blocks向我展示了这个:

错误:从类型“gameHistory

分配类型“struct gameHistory *”时出现不兼容的类型

但我认为struct已经很好地宣布了, 其他一点,  我为int time_max

分配内存

3 个答案:

答案 0 :(得分:2)

gameHistory gameHistory;是一个错误。 typename不能重新用作变量名。让我们假设你的意思是:

gameHistory history;

这已经分配了内存。您不需要分配任何额外的内存。只需从您的函数中删除尝试过的malloc行,一切都会正常。

然而,在你的功能中进一步下降会出现问题:

strcpy((*gameHistoryReaded).maze_size, token1);

到目前为止,您还没有在任何地方指出maze_size点,因此您无法将字符复制到其中。您可以将maze_size设为char数组(在这种情况下,它不需要更多分配),或者您可以分配空间并指向该空间:

gameHistoryReaded->maze_size = strdup(token1);

strdup功能一次完成mallocstrcpy

trophymoves出现同样的问题;最后你应该每次检查token1 != NULL

答案 1 :(得分:1)

你取消引用指针gameHistoryRead,它产生结构。要将malloc的结果赋给指针本身,请不要取消引用(省略*)。

为什么要将此指针传递给函数呢?它被立即覆盖。如果您打算将malloc的ed结构返回给调用者,则需要指向指针的指针(**gameHistoryRead)。在这种情况下,第一行是正确的,因为您正在指定指针本身。

刚刚注意到:你已经对结构进行了解释,那你为什么选择它呢?这没有任何意义(我想现在你想要填充传递的结构,但为什么malloc呢?)。

完全删除结构的malloc()或查看下面的代码。

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

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

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

struct的malloc大小是错误的。 sizeof(...)已经产生了正确的大小(除非你想返回一个数组,但更多的是错误的。)

在main()中:你不能对变量使用与变量相同的名称(你甚至不应该只考虑改变大小写 - 这会妨碍可读性);见main()。

图片的标题说明:

  • 不要像对malloc()的结果那样强制转换void *。有关说明,请参阅here
  • 使用前检查malloc的结果。它可以是NULL(没有可用的内存)。取消引用NULL指针会导致未定义的行为(UB)。这意味着任何事情都可能发生(甚至可以忽略不计)。
  • 不要使用(* p).m从指针访问结构的成员。相反,请使用专为此设计的->
  • 如果其他字段(maze_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;
}  

答案 2 :(得分:0)

gameHistoryReaded是指向gameHistory结构的指针。

这一行:

   *gameHistoryReaded = (gameHistory*)malloc(LENGTH_GAME_HISTORY*sizeof(gameHistory));

将从malloc()返回的值分配给gameHistoryReaded个点。

可能不是你想要的。

请勿使用*取消引用指针。