使用函数时出现意外的分段故障

  • 本文关键字:意外 分段 故障 函数 c
  • 更新时间 :
  • 英文 :


我在运行项目时遇到了一些意外的Segmentation Fault错误。具体来说,game_create_from_file函数(在game_loop_init内部(按预期运行并创建游戏结构。但我发现,当它结束时,我刚刚创建的游戏结构消失了,当我试图到达它时,我得到了一个分段故障。我想说的是,game_create_from_file中的game_print_data正在运行,但game_loop_init中的game_print_data遇到了分段故障。这些是涉及的文件:

game_look.c//game_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 argumentsn" );
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 argumentsn" );
return 1;
}
} else {
fprintf(stderr, "Wrong argumentsn" );
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("%ldn",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) : %sn", cmd_to_str[last_cmd-NO_CMD][CMDL], cmd_to_str[last_cmd-NO_CMD][CMDS], status);
}
}
}

game.c

/**
* @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;
}

game.h

/**
* @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);

变量的值"游戏";在函数game_ lop_init((中接收到的函数game_print_data((为NULL。由于函数game_create_from_file((没有更新"的值;游戏";在game_lop_init((中。

最新更新