Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@y_uehara1011

QQuickImageProviderを使うとプログラム終了時に不正終了する問題

More than 1 year has passed since last update.

問題

QQuickImageProviderを使ったプログラムでは、main.cpp内での登録方法に気を付けないとプログラム終了時に謎のエラーに遭遇することがある。

参照 → Qtを使った簡単なGUIアプリ(1) マンデルブロー集合を描いてみる

QtCreatorから実行した場合、メインウインドウを閉じるとQtCreatorのApplication Outputペインにこんなエラーが出る

20:51:15: Starting C:\git\build-QtMandelbrot-Qt_5_14_1_msvc2017_64-Release\release\QtMandelbrot.exe ...
20:51:23: The program has unexpectedly finished.
20:51:23: The process was ended forcefully.
20:51:23: C:\git\build-QtMandelbrot-Qt_5_14_1_msvc2017_64-Release\release\QtMandelbrot.exe crashed.

プログラムの動作自体は正常なのでなかなか気づかなかったが、気持ち悪いので修正したい。

原因

問題の箇所

main.cpp
    FractalDrawer fractalDrawer(sizeSettings.getCanvasWidth(), sizeSettings.getCanvasHeight());
    QQmlApplicationEngine engine;
    engine.addImageProvider(QLatin1String("fractalDrawer"), &fractalDrawer);
    engine.rootContext()->setContextProperty("fractalDrawer", &fractalDrawer);
FractalDrawer.h
class FractalDrawer : public QObject, public QQuickImageProvider
{
  • QObjectの派生クラスは、スタック上にインスタンスを確保してもメモリの管理はQtがよろしくやってくれる
  • QQuickImageProviderQObjectの派生クラスではないので、addImageProvider()の引数としてアドレスを渡すと、エンジン終了時にdeleteされてしまう
  • 今回の例ではFractalDrawerQObjectからも多重継承されているが、addImageProvider()からはQQmlImageProviderBase型として扱われる
  • 結果、スタックに置いてあるにも関わらずエンジン終了時にdeleteされる
  • main()終了時にメモリ解放しようとして二重解放でエラー

修正方法

スタックに置くのをやめてヒープに置くようにした

main.cpp
    auto *fractalDrawer = new FractalDrawer(sizeSettings.getCanvasWidth(), sizeSettings.getCanvasHeight());
    QQmlApplicationEngine engine;
    engine.addImageProvider(QLatin1String("fractalDrawer"), fractalDrawer);
    engine.rootContext()->setContextProperty("fractalDrawer", fractalDrawer);

感想

  • 多重継承はやっぱりやめたほうがいいかもしれない
  • QObjectをC#や基本型の変数のように気楽に定義できるQtの世界観は好きなのだけど、やはりC++ベースである以上この手の隙間的な問題はいろいろありそう
0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
y_uehara1011
歌って潜れる組み込み系エンジニア

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?