While debugging a crash, I came across this issue in some code:
int func() { char *p1 = malloc(...); if (p1 == NULL) goto err_exit; char *p2 = malloc(...); if (p2 == NULL) goto err_exit; ... err_exit: free(p2); free(p1); return -1; }
The problem occurs when the first malloc fails. Because we jump across the initialization of p2
, it contains random data and the call to free(p2)
can crash.
I would expect/hope that this would be treated the same way as in C++ where the compiler does not allow a goto to jump across an initialization.
My question: is jumping across an initialization allowed by the standard or is this a bug in gcc's implementation of c99?
You can ask gcc to warn you when you jump over a variable definition by using -Wjump-misses-init
and then you can use -Werror
(or, more precisely, -Werror=jump-misses-init
) to force the users to deal with it. This warning is included in -Wc++-compat
so the gcc developers are aware that the code behaves differently in C versus C++.
You could also change the code slightly:
int func() { char *p1 = malloc(...); if (p1 == NULL) goto err_exit_1; char *p2 = malloc(...); if (p2 == NULL) goto err_exit_2; ... err_exit_2: free(p2); err_exit_1: free(p1); return -1; }
... and just keep pairing labels with initialized variables. You'll have the same problem with calling many other functions with unitialized variables, free just happens to be a more obvious one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With