OP公开的代码可能会导致各种缺陷,从而导致失败:
QFile file("proc/stat"); 尝试在当前目录中打开proc/stat 。 如果这不是偶然的根目录,则可能无法打开OP期望的目录,或者只是失败。
应该用QFile file(" / proc/stat");代替QFile file(" / proc/stat"); 这将打开一个绝对路径(独立于当前目录)。
file.open(QIODevice::ReadOnly);成功file.open(QIODevice::ReadOnly); 未经测试。
如果成功,则返回true; 否则为假。
应该检查一下。
成功的std::sscanf(line.data(), "cpu %llu %llu %llu %llu", &totalUser, &totalUserNice, &totalSystem, &totalIdle); 也没有检查。
成功分配的接收参数的数量(如果在分配第一个接收参数之前发生匹配失败,则为零);如果在分配第一个接收参数之前发生输入失败,则为EOF。
我将OP的示例代码转换为MCVE,并添加了一些诊断程序来演示问题:
#include
namespace SysInfoLinuxImpl {
template
QVector cpuRawData();
} // namespace SysInfoLinuxImpl
template
QVector SysInfoLinuxImpl::cpuRawData()
{
QFile file(FIX ? "/proc/stat" : "proc/stat");
file.open(QIODevice::ReadOnly);
QByteArray line = file.readLine();
file.close();
qDebug() << "line:" << line;
qulonglong totalUser = 0, totalUserNice = 0, totalSystem = 0, totalIdle = 0;
int ret =
std::sscanf(line.data(), "cpu %llu %llu %llu %llu", &totalUser, &totalUserNice, &totalSystem, &totalIdle);
qDebug() << "sscanf(): " << ret;
qDebug() << "totalUser: " << totalUser;
qDebug() << "totalUserNice:" << totalUserNice;
qDebug() << "totalSystem: " << totalSystem;
qDebug() << "totalIdle: " << totalIdle;
QVector rawData;
rawData.append(totalUser);
rawData.append(totalUserNice);
rawData.append(totalSystem);
rawData.append(totalIdle);
return rawData;
}
int main()
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
// check original code
qDebug() << "with 'proc/stat'";
SysInfoLinuxImpl::cpuRawData();
// check fixed code
qDebug() << "with '/proc/stat'";
SysInfoLinuxImpl::cpuRawData();
return 0;
}
我在cygwin上编译和测试了代码(我在Windows 10上),并得到以下输出:
Qt Version: 5.9.4
with 'proc/stat'
QIODevice::read (QFile, "proc/stat"): device not open
line: ""
sscanf(): -1
totalUser: 0
totalUserNice: 0
totalSystem: 0
totalIdle: 0
with '/proc/stat'
line: "cpu 137982341 0 106654637 1152709669\n"
sscanf(): 4
totalUser: 137982341
totalUserNice: 0
totalSystem: 106654637
totalIdle: 1152709669
最后,我不太确定为什么OP声称
应用程序崩溃了。
我坚信崩溃不会在公开的代码中发生(而是在其他地方)。 我认为是因为:
QByteArray line = file.readLine(); (当尝试从无法打开的file中读取时)会导致一个空数组( QIODevice::readLine() , QByteArray ),但即使是一个空数组也始终确保数据后跟一个'\\ 0'终止符 。
因此,接入到line.data()中std::sscanf(line.data(), "cpu %llu %llu %llu %llu", &totalUser, &totalUserNice, &totalSystem, &totalIdle); 即使没有分配任何变量也应该是安全的。 即使sscanf()失败,变量也会被初始化并具有定义的值。
rawData.append()的最终调用可能会分配内存,这可能会失败,但是,再次,我看不到这里会崩溃。
因此,除了任何其他先前执行的代码导致未定义行为 (意外地在暴露的代码中开始变得可见)之外,我不知道该代码可能会崩溃的原因。