QT中TableWidget获取项失败引发程序异常退出问题求助
分析与修复你的Qt进程优先级设置崩溃问题
看起来你的程序崩溃根源是空指针解引用,而且这个问题不在你写的try-catch覆盖范围内——空指针访问属于操作系统级别的内存错误(比如SIGSEGV信号),不是C++标准异常,所以你的try块根本抓不到它,程序会直接终止。
具体问题点拆解
- 无效行索引导致空指针:当用户没有选中表格任何行时,
ui->tableWidget->currentRow()会返回-1,这时候你直接用curI去获取item(curI,1),会得到nullptr,调用->text()瞬间触发崩溃。 - 单元格Item可能不存在:即使
curI是有效索引,tableWidget->item(curI,1)也可能是nullptr(比如该行该列没有主动创建QTableWidgetItem),同样会触发空指针崩溃。 try-catch的局限性:你写的catch(int x)只能捕获你主动抛出的int类型异常,对内存错误、数组越界这类底层问题完全无效。
修复后的代码
我调整了逻辑,把所有前置检查放在前面,同时增加系统调用的错误处理:
#include <errno.h> #include <string.h> void MainWindow::on_priority_clicked() { int curI = ui->tableWidget->currentRow(); int prio = ui->prioritySpinBox->value(); // 1. 先检查是否选中了有效行 if (curI < 0 || curI >= ui->tableWidget->rowCount()) { QMessageBox::warning(this, "Error", "Please select a valid process row first"); return; } // 2. 检查目标单元格的Item是否存在且有内容 QTableWidgetItem* targetItem = ui->tableWidget->item(curI, 1); if (!targetItem || targetItem->text().isNull()) { QMessageBox::warning(this, "Error", QString("Process %1 is not created").arg(curI + 1)); return; } // 3. 检查pid数组的索引是否有效(防止表格行数和pid数组长度不一致) if (curI >= pid.size()) { QMessageBox::warning(this, "Error", "Internal error: PID array mismatch"); return; } // 4. 设置优先级,同时检查系统调用是否失败 errno = 0; // 重置errno,因为getpriority成功也可能返回-1 int setResult = setpriority(PRIO_PROCESS, pid.at(curI), prio); if (setResult == -1 && errno != 0) { QMessageBox::warning(this, "Error", QString("Failed to set priority: %1").arg(strerror(errno))); return; } // 5. 获取并显示新的优先级,同样检查调用是否成功 errno = 0; int newPrio = getpriority(PRIO_PROCESS, pid.at(curI)); if (newPrio == -1 && errno != 0) { QMessageBox::warning(this, "Error", QString("Failed to get priority: %1").arg(strerror(errno))); return; } // 更新表格显示 QLabel *labelPrio = new QLabel(ui->tableWidget); labelPrio->setText(QString::number(newPrio)); labelPrio->setAlignment(Qt::AlignCenter); // 可选:让文本居中显示 ui->tableWidget->setCellWidget(curI, 3, labelPrio); }
关键修复说明
- 所有潜在的无效访问都提前做了检查,从根源避免空指针和数组越界
- 增加了
setpriority/getpriority的错误判断:这两个函数成功时也可能返回-1(比如优先级本身就是-1),所以必须结合errno来判断是否真的出错 - 去掉了无用的
try-catch,改用前置检查+即时错误提示的方式,逻辑更清晰也更安全
内容的提问来源于stack exchange,提问作者Jugennd
相关产品推荐
相关产品推荐

