Any decent linter will flag numerous problems with this code. Here’s what the one provided with Atom editor found, plus what I eyeballed.
int lookup_personal_info(char *first_name, void *last_name, uint8_t (*sin)[9], const struct **info_out)
last_name
is declaredvoid *
but used as achar *
const struct **info_out
declares an anonymous struct. It should bepersonal_info **info_out
- The function returns a
bool
not anint
. sin
is never used except to check it’s passed in.
if (!first_name || !last_name || !sin)
return false;
- Passing in a null pointer is probably a bug by the caller. This silently ignores that bug making it difficult to find. It should raise an error.
- It forgets to check
info_out
.
char *initials[3] = { first_name[0], last_name[1] };
- This is an array of character pointers being initialized with
char
. It should bechar initials[3]
. - It is not null terminated. Maybe it doesn’t have to be, but I wouldn’t risk that.
last_name
is declaredvoid *
yet used as achar *
.- It’s using the first character of
first_name
as an initial, that makes sense, but why the second… thing… inlast_name
?
personal_info *data = malloc(sizeof(struct personal_info));
struct personal_info
is not a type, the type is personal_info
.
*info_out = (personal_info *) data;
info_out
was incorrectly declared as an anonymous struct. It should be personal_info **info_out
. Then no type cast is necessary.
bool is_ok = database_lookup(initials, &data);
if (is_ok)
goto fail;
The check is backwards.
The use of goto
is justified to ensure proper cleanup on error. It’s probably included in the example as a red herring.
fail:
data = NULL;
free(data);
return true;
free
is called after nulling outdata
leaking memory.- There’s no need to set
data
toNULL
, it’s local to the function which will shortly exit. - Both failure and success return
true
.