First of all please excuse me, I can't reproduce the problem, it comes from a big project and when I recover the functions one by one in a more minimalist file it suddenly works (without modifying almost anything) and I can't understand where it can come from.
First of all the project contains these structures:
typedef struct {
uint32_t x, y;
uint16_t w, h;
char* str;
} Text;
typedef struct {
uint32_t last_tick;
uint32_t delta_ms;
float delta;
float t_fps;
uint16_t fps;
} Clock;
I initialize the Text
structure which is present in another structure that I will call Other
from an initialization function for Other
like this:
other->text_frame_rate = (Text){ 0,0,0,0, (char[8]){} };
It is supposed to contain text that looks like this FPS: 60
.
Then I use snprintf
to write the desired text to it in another function, like this:
void _render_frame_rate(Other* other, Clock clock)
{
snprintf(other->text_frame_rate.str, 8, "FPS: %d", clock->fps);
...
}
This _render_frame_rate
function is itself called from another function which looks like this at the parameter level void Render_game(SDL_Renderer* renderer, Other* other, Clock* clock);
But I get a segfault unless I redefine the frame again in _render_frame_rate
like this:
void _render_frame_rate(Other* other, Clock clock)
{
other->text_frame_rate = (Text){ 0,0,0,0, (char[8]){} }; // redefine and no problem
snprintf(other->text_frame_rate.str, 8, "FPS: %d", clock->fps);
...
}
And in this case, where the struct Text
has been redefined it finally works.
I also checked with a printf("%p\n");
if the address of the pointer was always the same at initialization and at the display function and yes it remains the same.
I also specify that at no time is the text_frame_rate
value used or modified elsewhere.
What do you think could be causing this behavior?
UPDATE: Thanks to @IanAbbott's hint I was able to solve the problem by dynamically allocating text_frame_rate
like this:
other->text_frame_rate = (Text){ 0,0,0,0, NULL };
other->text_frame_rate.str = malloc(8);
CodePudding user response:
Here is one erroneous example:
void init_other_text_frame_rate(Other *other)
{
other->text_frame_rate = (Text){0, 0, 0, 0, (char[8]){0}};
}
void render_frame_rate(Other* other, Clock clock)
{
snprintf(other->text_frame_rate.str, 8, "FPS: %d", clock->fps);
}
void foo(Other* other, Clock clock)
{
init_other_text_frame_rate(other, clock);
render_frame_rate(other, clock); // invalid!
}
The lifetime of the array of char
pointed to by other->text_frame_rate.str
expired when init_other_text_frame_rate(other, clock);
returned to foo
, so its use in the call to snprintf
is invalid.