在调试崩溃时,我在一些代码中遇到了这个问题:
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;
}
当第一个 malloc 失败时就会出现问题。因为我们跳过了 p2
的初始化,所以它包含随机数据,并且对 free(p2)
的调用可能会崩溃。
我期望/希望这会被以与 C++ 中相同的方式处理,其中编译器不允许 goto 跳过初始化。
我的问题:是跳过标准允许的初始化还是这是 gcc 的 c99 实现中的错误?
最佳答案
当您使用 -Wjump-misses-init
跳过变量定义时,您可以要求 gcc 发出警告,然后您可以使用 -Werror
(或者,更多准确地说,-Werror=jump-misses-init
)来强制用户处理它。此警告包含在 -Wc++-compat
中因此 gcc 开发人员知道代码在 C 和 C++ 中的行为有所不同。
您还可以稍微更改代码:
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;
}
...并继续将标签与初始化变量配对。使用统一变量调用许多其他函数时,您也会遇到同样的问题,free 只是一个更明显的问题。
关于c99 转到过去的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40379107/