我是c的新手。我在C中遇到了这段代码,它被标记为错误代码。不知道为什么它不好,还有改进的建议吗?
原始代码来自此链接:
typedef struct {
bool is_married;
uint8_t age;
uint8_t num_children;
} personal_info;
int lookup_personal_info(char *first_name, void *last_name, uint8_t (*sin)[9], const struct **info_out)
{
// Sanity check.
if (!first_name || !last_name || !sin)
return false;
char *initials[3] = { first_name[0], last_name[1] };
// Allocate space for the output.
personal_info *data = malloc(sizeof(struct personal_info));
if (!data)
goto fail;
// Look up the personal info by initials.
bool is_ok = database_lookup(initials, &data);
if (is_ok)
goto fail;
// Assign the found data to the output parameter.
*info_out = (personal_info *) data;
// Success!
return true;
fail:
data = NULL;
free(data);
return true;
}
答案 0 :(得分:2)
在调用NULL
之前设置指向free
的指针会使对free
的调用变为良性(即不执行任何操作)。
如果您的IDE中有一个静态分析工具可以检查并且可能是不正确的代码,那么它被它选中就不会感到惊讶。
安全地调用free
的惯用方式是将free
-d指针设置为NULL
,在调用之后 而不是之前。
答案 1 :(得分:2)
任何体面的linter都会用此代码标记许多问题。这是Atom editor提供的内容,加上我的目光。
int lookup_personal_info(char *first_name, void *last_name, uint8_t (*sin)[9], const struct **info_out)
last_name
被声明为void *
,但用作char *
const struct **info_out
声明了一个匿名结构。应该是personal_info **info_out
bool
而不是int
。sin
仅用于检查它是否传入。 if (!first_name || !last_name || !sin)
return false;
info_out
。 char *initials[3] = { first_name[0], last_name[1] };
char
初始化的字符指针数组。应该是char initials[3]
。last_name
被声明为void *
,但仍被用作char *
。first_name
的第一个字符作为首字母,这是有道理的,但是为什么在last_name
中使用第二个……东西呢? personal_info *data = malloc(sizeof(struct personal_info));
struct personal_info
不是类型,类型是personal_info
。
*info_out = (personal_info *) data;
info_out
被错误地声明为匿名结构。它应该是personal_info **info_out
。这样就不需要类型转换了。
bool is_ok = database_lookup(initials, &data);
if (is_ok)
goto fail;
检查是向后的。
使用goto
可以确保正确清除错误。该示例中可能包含红色鲱鱼。
fail:
data = NULL;
free(data);
return true;
free
泄漏的内存之后,调用data
。data
设置为NULL
,因为它对于即将退出的函数是本地的。true
。答案 2 :(得分:0)
这对我来说没有多大意义。为什么释放NULL
指针...
fail:
data = NULL;
free(data);