You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Михаил Беляков

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:24:51