Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.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 - Fatal编程技术网

C 使用函数时出现意外的分段错误

C 使用函数时出现意外的分段错误,c,C,在运行项目时,我遇到了一些意外的分段错误。具体来说,game\u create\u from_file函数(在game\u loop\u init中)按预期运行并创建游戏结构。但我发现,当它结束时,我刚刚创建的游戏结构消失了,当我试图达到它时,我得到了一个分割错误。我想说的是game\u print\u data在game\u create\u from\u file中运行,但是game\u print\u data在game\u loop\u init中运行时遇到Seg故障。以下是涉及的文件:

在运行项目时,我遇到了一些意外的分段错误。具体来说,
game\u create\u from_file
函数(在
game\u loop\u init
中)按预期运行并创建游戏结构。但我发现,当它结束时,我刚刚创建的游戏结构消失了,当我试图达到它时,我得到了一个分割错误。我想说的是
game\u print\u data
game\u create\u from\u file
中运行,但是
game\u print\u data
game\u loop\u init
中运行时遇到Seg故障。以下是涉及的文件:

game\u loop.c//game\u reader.h包括game.h

/**
 * @brief It defines the game loop
 *
 * @file game_loop.c
 * @author Profesores PPROG
 * @version 1.0
 * @date 13-01-2015
 * @copyright GNU Public License
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "graphic_engine.h"

/**
 * @brief Initialize the game loop
 *
 * game_loop_init will initianlize the Game and Graphic_engine
 * structs to run the game loop
 *
 * @date 13-01-2015
 * @author Profesores PPROG
 *
 * @param game  the Game struct to be initialized
 * @param gengine  the Graphic_engine struct to be initialized
 * @param file_name  the file that contains the game board
 * @return 1 in case of an error or else 0
 */
int game_loop_init(Game game, Graphic_engine **gengine, char *file_name);

/**
 * @brief Runs the game loop
 *
 * game_loop_run will run the game loop until the game ends
 *
 * @date 13-01-2015
 * @author Profesores PPROG
 *
 * @param game  the Game struct that holds the game's data
 * @param gengine  the Graphic_engine struct that holds game's data to be printed
 */
void game_loop_run(Game game, Graphic_engine *gengine, FILE* file);

/**
 * @brief Terminates the game loop
 *
 * game_loop_cleanup will destroy the game and the Graphic_engine
 *
 * @date 13-01-2015
 * @author Profesores PPROG
 *
 * @param game  the Game struct to be destroyed
 * @param gengine  the Graphic_engine struct to be destroyed
 */
void game_loop_cleanup(Game game, Graphic_engine *gengine);


int main(int argc, char *argv[]) {
  Game game = NULL;
  Graphic_engine *gengine;
  FILE* file = NULL;

  if (argc < 2) {
    fprintf(stderr, "Use: %s <game_data_file>\n", argv[0]);
    return 1;
  }

  if ((argc < 4) && (argc > 2)) {
    fprintf(stderr, "Wrong number of arguments\n" );
    return 1;
  }

  if (argc == 4) {
    if (strcmp(argv[2],"-l") == 0) {
      if (strcmp(argv[3],"LOG") == 0) {
        file = fopen(argv[3],"w");
      } else {
        fprintf(stderr, "Wrong arguments\n" );
        return 1;
      }
    } else {
      fprintf(stderr, "Wrong arguments\n" );
      return 1;
    }
  }

  if (!game_loop_init(game, &gengine, argv[1])){
    game_loop_run(game, gengine, file);
    game_loop_cleanup(game, gengine);
  }

  if (file != NULL){
    fclose(file);
  }

  return 0;
}

int game_loop_init(Game game, Graphic_engine **gengine, char *file_name){
  if (game_create_from_file(game, file_name) == ERROR) {
    fprintf(stderr, "Error while initializing game.\n");
    return 1;
  }

  if ((*gengine = graphic_engine_create()) == NULL) {
    fprintf(stderr, "Error while initializing graphic engine.\n");
    game_destroy(game);
    return 1;
  }
  game_print_data(game);
  return 0;
}

void game_loop_run(Game game, Graphic_engine *gengine, FILE* file){
  extern char *cmd_to_str[N_CMD][N_CMDT];
  T_Command command = NO_CMD;
  printf("%ld\n",game_get_player_location(game) );
  game_print_data(game);
  while ((command != EXIT) && !game_is_over(game)) {
    graphic_engine_paint_game(gengine, game);
    command = command_get_user_input();
    game_update(game, command);

    if (file != NULL) {
      char status[255] = "";
      T_Command last_cmd = game_get_last_command(game);
      if (game_get_last_command_status(game) == OK){
        strcpy(status,"OK");
      } else {
        strcpy(status,"ERROR");
      }

      fprintf(file, " %s (%s) : %s\n", cmd_to_str[last_cmd-NO_CMD][CMDL], cmd_to_str[last_cmd-NO_CMD][CMDS], status);
    }
  }
}

函数game\u print\u data()从函数game\u create\u from\u file()接收的变量“game”的地址为空


函数game_create_from_file()未更改game_create_from_file()中“game”的地址。

函数game_print_data()在函数game_create_from_file()中接收到的变量“game”的地址为空


函数game_create_from_file()未更改game_create_from_file()中“game”的地址。

game=game_create(game)
。在C中,所有函数参数都是通过值传递的。因此,函数中的
game
变量与调用方的
game
变量不同。您正在更改局部变量,而调用方的
game
仍为
NULL
。您需要从函数中返回
game
值,并将其分配回调用方。或者您需要将
游戏*
传入函数。顺便说一下,我强烈建议您不要键入def指针。它只是模糊了真正的类型,使代码更难理解。@kaylum命令
game=gmae\u create(game)
是错误的,因为函数的原型是
game\u create()
。我的错就在那。但在本例中,在game_create_from_file()函数中,game参数与您所说的main中的参数不同,对不知道您的typedef的读者来说,问题是游戏是指针而不是通过值传递的结构,这一点并不明显。我假设Graphic_engine是一个结构而不是指向结构的指针,因为您将指针传递给Graphics_引擎而不仅仅是Graphics_引擎?因此,存在不一致性,这可能令人困惑。您的
@param
注释不区分,它们都称这两个为“struct”。
game=game\u create(game)
。在C中,所有函数参数都是通过值传递的。因此,函数中的
game
变量与调用方的
game
变量不同。您正在更改局部变量,而调用方的
game
仍为
NULL
。您需要从函数中返回
game
值,并将其分配回调用方。或者您需要将
游戏*
传入函数。顺便说一下,我强烈建议您不要键入def指针。它只是模糊了真正的类型,使代码更难理解。@kaylum命令
game=gmae\u create(game)
是错误的,因为函数的原型是
game\u create()
。我的错就在那。但在本例中,在game_create_from_file()函数中,game参数与您所说的main中的参数不同,对不知道您的typedef的读者来说,问题是游戏是指针而不是通过值传递的结构,这一点并不明显。我假设Graphic_engine是一个结构而不是指向结构的指针,因为您将指针传递给Graphics_引擎而不仅仅是Graphics_引擎?因此,存在不一致性,这可能令人困惑。您的
@param
注释没有区别,它们都称这两个为“struct”。
/**
 * @brief It implements the game interface and all the associated callbacks
 * for each command
 *
 * @file game.c
 * @version 1.0
 * @author Profesores PPROG
 * @date 13-01-2015
 * @copyright GNU Public License
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "game_reader.h"

#define N_CALLBACK 9            //The number of callbacks for the commands
#define PLAYER_ID 24            //This is the player_id that the player is initialized with during the game creation by the game_create function
#define OBJECT_ID 8             //This is the object_id that the object is initialized with during the game creation by the game_create function

 struct _Game{
  Player* player;                        // A pointer to the player of the game
  Object* objects[MAX_OBJECTS + 1];      // A matrix with all the objects of the game
  Space* spaces[MAX_SPACES + 1];         // A matrix with all the spaces of the game
  Die* die;                              // A pointer to the die of the game
  T_Command last_cmd;                    // The last command executed in a game
  STATUS last_cmd_status;                // The status of the last command executed in a game
};

/**
   Define the function type for the callbacks
*/
typedef STATUS (*callback_fn)(Game game);

/**
   List of callbacks for each command in the game
*/
STATUS game_callback_unknown(Game game);   //A callback for the UNKNOWN command
STATUS game_callback_exit(Game game);      //A callback for the EXIT command
STATUS game_callback_next(Game game);      //A callback for the NEXT command
STATUS game_callback_back(Game game);      //A callback for the BACK command
STATUS game_callback_take(Game game);      //A callback for the TAKE command
STATUS game_callback_drop(Game game);      //A callback for the DROP command
STATUS game_callback_roll(Game game);      //A callback for the ROLL command
STATUS game_callback_left(Game game);      //A callback for the LEFT command
STATUS game_callback_right(Game game);     //A callback for the RIGHT command

static callback_fn game_callback_fn_list[N_CALLBACK]={
  game_callback_unknown,
  game_callback_exit,
  game_callback_next,
  game_callback_back,
  game_callback_take,
  game_callback_drop,
  game_callback_roll,
  game_callback_left,
  game_callback_right};

/**
   Private functions
*/

/**
 * @brief Gets a space from a game
 *
 * Gets an index as input and returns the space that is in that position in the spaces[]
 * matrix in the game
 *
 * @author Profesores PPROG
 * @date 13-01-2015
 *
 * @param game the game struct from which the space will be returned
 * @param position the position of the space in the spaces[] matrix in the game
 * @return the id of that space
 */
Id game_get_space_id_at(Game game, int position);

/**
 * @brief Gets a objects from a game
 *
 * Gets an index as input and returns the objects that is in that position in the objectss[]
 * matrix in the game
 *
 * @author Evangelos Lazarakis
 * @date 03-03-2020
 *
 * @param game the game struct from which the objects will be returned
 * @param position the position of the objects in the objectss[] matrix in the game
 * @return the id of that objects
 */
Id game_get_object_id_at(Game game, int position);

/**
 * @brief Sets the player's location Id in a game
 *
 * @author Evangelos Lazarakis
 * @date 10-02-2020
 *
 * @param game the game struct in which the player location Id is going to change
 * @param id the Id of the space that the player is located
 * @return a STATUS code, ERROR if any error occures or OK
 */
STATUS game_set_player_location(Game game, Id id);

/**
 * @brief Sets an object's location in a game
 *
 * Gets a space Id and an object Id and adds the later
 * in the space's set of objects
 *
 * @author Evangelos Lazarakis
 * @date 10-02-2020
 *
 * @param game the game struct in which the object location Id is going to change
 * @param object_id the Id of the object whose location we want to set
 * @param space_id the Id of the space in which we want to place the object
 * @return a STATUS code, ERROR if any error occures or OK
 */
STATUS game_set_object_location(Game game, Id object_id, Id space_id);


/**
   Game interface implementation
*/

Game game_create() {
  int i;
  Game game = malloc(sizeof(*game));
  for (i = 0; i <= MAX_SPACES; i++) {
    game->spaces[i] = NULL;
  }

  for (i = 0; i <= MAX_OBJECTS; i++) {
    game->objects[i] = NULL;
  }

  game->player = player_create(PLAYER_ID);              //The player is always initialized with the PLAYER_ID
  game->die = die_create(1);                            //The die is always initialized with the value 1
  game->last_cmd = NO_CMD;
  game->last_cmd_status = OK;

  return game;
}

STATUS game_create_from_file(Game game, char* filename) {

  if ((game = game_create()) == NULL)
    return ERROR;

  if (game_reader_load_spaces(game, filename) == ERROR)
    return ERROR;

  if (game_reader_load_objects(game, filename) == ERROR)
    return ERROR;

  game_set_player_location(game, game_get_space_id_at(game, 0));
  game_print_data(game);
  return OK;
}
/**
 * @brief It defines the game interface
 * for each command
 *
 * @file game.h
 * @author Profesores PPROG
 * @version 1.0
 * @date 13-01-2015
 * @copyright GNU Public License
 */

#ifndef GAME_H
#define GAME_H

#include "command.h"
#include "space.h"
#include "player.h"
#include "object.h"
#include "die.h"


/**
 * @brief The Game structure
 * Stores the data of a game
 *
 * @author Profesores PPROG
 * @date 13-01-2015
 */
typedef struct _Game* Game;

/**
 * @brief Creates a game
 *
 * Initializes all the fields of a Game struct
 *
 * @author Profesores PPROG
 * @date 13-01-2015
 *
 * @param game the game struct that is going to be initialized
 * @return a STATUS code, ERROR if any error occures or OK
 */
Game game_create();

/**
 * @brief Creates a game from an open file
 *
 * Initializes all the fields of a Game struct using the game_create function
 * and sets the location of the player and the object on the game board
 *
 * @author Profesores PPROG
 * @date 13-01-2015
 *
 * @param game the game struct that is going to be initialized
 * @param filename the name of the file from which the function is giong to get data
 * @return a STATUS code, ERROR if any error occures or OK
 */
STATUS game_create_from_file(Game game, char* filename);

/**
 * @brief Updates a game
 *
 * Updates a game by executing the command that it gets as input
 *
 * @author Profesores PPROG
 * @date 13-01-2015
 *
 * @param game the game struct that is going to be updated
 * @param cmd the command that is going to be executed
 * @return a STATUS code, ERROR if any error occures or OK
 */
STATUS game_update(Game game, T_Command cmd);

/**
 * @brief Destroys a game
 *
 * @author Profesores PPROG
 * @date 13-01-2015
 *
 * @param game the game struct that is going to be destroyed
 * @return a STATUS code, ERROR if any error occures or OK
 */
STATUS game_destroy(Game game);

/**
 * @brief Returns FALSE
 *
 *
 * @author Profesores PPROG
 * @date 13-01-2015
 *
 * @param game the game struct that is not over
 * @return a BOOL code, FALSE if the game is not over
 */
BOOL game_is_over(Game game);

/**
 * @brief Prints the data of a game
 *
 *
 * @author Profesores PPROG
 * @date 13-01-2015
 *
 * @param game the game struct that is going to be printed
 */
void game_print_data(Game game);