I was reading about structs in C that there are 2 ways to define a struct variable (which initializes it and creates memory for it).
EDIT: I found the answer. The reason it was not working was because the game_struct variable got destroyed as soon as the game_create function exited and then I was left with an address to a place in memory that I was not allowed to access anymore. And the reason that the malloc version worked was because it allocated memory for the struct and I passed back the value of the address.
- First way is to simply define it as a normal variable like this
struct Person {
char name[50];
int age;
float salary;
};
int main() {
struct Person person1, person2;
strcpy(person1.name, "Joey Gladstone");
person1.age = 13;
}
- The second way is to use
malloclike this.
struct game * game_create()
{
struct game * game;
game = malloc(sizeof(struct game));
return game;
}
But when I tried to use the first way in my game it showed me this error:
[1] 2640483 segmentation fault (core dumped) ./game
Here is my struct defined in game.h
#ifndef __GAME_H__
#define __GAME_H__
#include <SDL2/SDL.h>
#include <stdbool.h>
// Struct for displaying text on screen
typedef struct {
SDL_Rect rect;
SDL_Texture * texture;
} text;
// Ship orientation
typedef enum {
HORIZONTAL,
VERTICAL
} orientation;
typedef struct {
SDL_Rect rect;
bool is_placed;
orientation orientation;
} ship;
typedef struct {
SDL_Rect rect;
bool is_hit;
} shot;
struct game {
text title;
SDL_Window * window;
SDL_Renderer * renderer;
SDL_Rect player_aim;
shot player_shots[100];
shot opponent_shots[100];
ship player_ships[10];
ship opponent_ships[10];
bool is_running;
int cell_size;
int grid_width;
int grid_height;
int grid_offset_y;
int placing_ship_index;
int player_grid_offset_x;
int opponent_grid_offset_x;
int placed_ships;
int player_hits;
int opponent_hits;
int player_shots_count;
int opponent_shots_count;
bool is_shooting;
};
struct game * game_create();
void game_run(struct game * game);
void game_init(struct game * game);
int game_terminate(struct game * game);
void game_quit(struct game * game);
text game_get_title(struct game * game);
#endif
And this is how I try to create the struct variable:
#include "include/game.h"
struct game * game_create()
{
struct game game_struct;
return &game_struct;
}
And I get segmentation fault error and I don’t understand why, I think it should have worked. What am I doing wrong? It works with malloc but does not work like this.
>Solution :
In this function:
struct game * game_create()
{
struct game game_struct;
return &game_struct;
}
The lifetime of game_struct ends at the end of the function scope, because it is a local variable created on the stack. It is cleared from the stack when the function returns.
If you want it to outlive the functions lifetime, you should create it on the heap using malloc as in your example above. Don’t forget to free when you are done with it.
See: storage durations of variables in C.