1

我有一个函数可以读取一个大文件来填充一个 QStringList。程序崩溃可能是因为没有足够的内存,因为如果我使用一个小文件,程序运行良好。我尝试通过捕获异常来调试问题。

QStringList readlargefile(QString filename)
{
    QStringList result;
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"cannot open file: "<<filename;
        return result;
    }
    QTextStream in(&file);
    in.setCodec("UTF-8");
    QString line;

    while(in.readLineInto(&line))
    {
        if(!line.isEmpty())
            result<<line;
    }

    file.close();
    return result;
}


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QStringList result;
    try
    {
        qDebug()<<"reading file";
        result=readlargefile("largefile.txt");
    }
    catch(...) {
        qFatal("got exception");
    }
}

输出是:

reading file
Killed

我无法捕捉到异常,为什么?

4

1 回答 1

1

如果您的程序被操作系统中止,它不会产生任何异常。但是您可以设置一个信号处理程序:

void signalHandler(int)
{
    //...
}

int main(int argc, char* argv[])
{
    signal(SIGINT  , signalHandler);
    signal(SIGTERM , signalHandler);
#ifdef Q_OS_WIN
    signal(SIGBREAK, signalHandler);
#endif

您无法捕获的原因std::bad_alloc是因为 Qt 可能使用了::new. 或者new可以,但公主在另一座城堡。

对于原始问题(崩溃),您可能会遇到两个陷阱。

1. 这可能是一个重新分配的问题。

当数组已经填满,并且您尝试插入更多时,它会分配一个新数组并从前一个数组复制(移动)数据。所以你最终有两个大数组,直到复制(移动)完成。如果您知道字符串的确切数量,您可以尝试预先分配数组以确保不会发生重新分配。为此使用QList::reserve()

2. QList 和 QVector 等 Qt 容器可以容纳不超过 2GB 的数据。

如果sizeof(QString)是 8 个字节,则最多允许 2^28 个项目。

如果您尝试存储更多,它最终会崩溃。尝试std::vector(with reserve) 并检查它是否有效。

毕竟,如果你的系统没有足够的内存来完成任务——它没有足够的内存,你无能为力,只能改变你的算法。

于 2020-10-12T07:02:54.393 回答