Qt程序堆内存问题求助:启动触发0xC0000005等崩溃错误
Qt程序启动时内存错误(退出码0xC0000005/0xC0000374)的修复方案
问题根源
代码中ColorfulCircle和QSlider是栈上创建的局部对象,调用layout->addWidget时,Qt会自动将它们的父对象设置为窗口window。Qt父子对象机制规定,父对象销毁时会自动销毁所有子对象,但main函数中局部栈对象的销毁顺序是先销毁slider、circle,再销毁window。当window销毁时,会尝试再次销毁已被栈自动回收的子对象,触发双重析构,导致内存访问违规(0xC0000005)和堆损坏(0xC0000374)错误。
修复代码
将栈上创建的widget改为堆内存创建,让Qt的父子机制正确管理生命周期:
#include <iostream> #include <QApplication> #include <QWidget> #include <QVBoxLayout> #include <QSlider> #include <QPixmap> #include <QPainter> #include <QPaintEvent> class ColorfulCircle : public QWidget { Q_OBJECT public: ColorfulCircle(QWidget *parent) { setParent(parent); mGreenCircle = QPixmap("GreenCircle.png"); mYellowCircle = QPixmap("YellowCircle.png"); mRedCircle = QPixmap("RedCircle.png"); if (mGreenCircle.isNull() || mYellowCircle.isNull() || mRedCircle.isNull()) { std::cerr << "Failed to load circle images!" << std::endl; return; } mCurrentCircle = mGreenCircle; setFixedSize(100, 100); } QSize minimumSizeHint() const override { return QSize(100, 100); } protected: void paintEvent(QPaintEvent *e) override { QPainter p(this); p.drawPixmap(e->rect(), mCurrentCircle); } public slots: void setGreen() { mCurrentCircle = mGreenCircle; update(); } void setYellow() { mCurrentCircle = mYellowCircle; update(); } void setRed() { mCurrentCircle = mRedCircle; update(); } private: QPixmap mCurrentCircle; QPixmap mGreenCircle; QPixmap mYellowCircle; QPixmap mRedCircle; }; int main(int argc, char **argv) { QApplication app(argc, argv); QWidget window; window.setWindowTitle("Colorful Circle"); window.setFixedSize(200, 250); QVBoxLayout *layout = new QVBoxLayout(&window); // 改为堆内存创建 ColorfulCircle *circle = new ColorfulCircle(nullptr); layout->addWidget(circle, 0, Qt::AlignCenter); // 改为堆内存创建 QSlider *slider = new QSlider(Qt::Horizontal); slider->setRange(0, 100); layout->addWidget(slider); QObject::connect(slider, &QSlider::valueChanged, [circle](int newValue) { if (newValue < 33) { circle->setGreen(); } else if (newValue < 66) { circle->setYellow(); } else { circle->setRed(); } }); window.show(); return app.exec(); } #include <main.moc>
额外检查点
确保GreenCircle.png、YellowCircle.png、RedCircle.png位于程序运行目录,或使用完整文件路径加载,避免图片加载失败引发后续异常。
内容的提问来源于stack exchange,提问作者Михаил Беляков
相关产品推荐
相关产品推荐

