资源泄漏或误报

Resource leak or false positive

我有这样的代码:

std::string getInfo(FILE *fp)
{
    char buffer[30];
    if (fread(buffer, 19, 1, fp) == 1)
        buffer[19] = '[=10=]';
    else
        buffer[0] = '[=10=]';

    return buffer;
}

我正在使用 cppcheck 进行静态分析,它发出警告:

error: Resource leak: fp [resourceLeak]
 return buffer;
 ^

在我看来,由于 return 是按值,数据将从“缓冲区”复制到 std::string 的存储中,因此那里没有泄漏。

这会带来一些实际问题还是误报?

error: Resource leak: fp [resourceLeak]

您没有从该函数泄漏任何资源。所以,如果您只分析这个函数,那么这是您的 cppcheck 中的错误。然而,正如@Taekahn 指出的那样——也许泄漏是在你程序的其他地方。

此外,由于您要返回 std::string,因此您可以使用 constructor taking a pointer and a count,而不必担心缓冲区中的“\0”:

std::string getInfo(FILE *fp)
{
    static constexpr const std::size_t info_length { 19 };
    char buffer[info_length];
    if (fread(buffer, info_length, 1, fp) == 1)
        return {buffer, info_length};
    else
        return {};
}

如果您使用的是 C++23,您可以考虑返回 而不是空字符串,例如类似于:

std::expected<std::string, errc> getInfo(FILE *fp)
{
    static constexpr const std::size_t info_length { 19 };
    char buffer[info_length];
    if (fread(buffer, info_length, 1, fp) == 1)
        return std::string{buffer, info_length};
    else
        return std::unexpected{errno};
}

显示的函数没有泄漏。

作为参数提供的 std::FILE* 可能是使用 std::fopen 创建的,如果该资源在某个时候未关闭,则可能会泄漏。但是因为这个函数不获取资源,所以这个函数也不应该负责释放它。

总之,它要么是误报,要么是误导性诊断。充其量(从诊断的角度来看),其他地方可能存在泄漏,尽管示例中未证明这一点。


P.S。因为你 return a std::string,你可以通过直接读入 std::string:

来避免先将内容复制到单独的缓冲区中
constexpr std::size_t count = 19;
std::string buffer(count, '[=10=]');
std::size_t r = fread(buffer.data(), count, 1, fp);
if (r)
    return buffer;
else
    return {};