资源泄漏或误报
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 {};
我有这样的代码:
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 {};