質問: 発生しているものとしては Segmentation faultになるのですが 色々デバッグしている中で何とか分かったのは デストラクタ後にデストラクタが走ったクラスのスロットが動作し続けてしまっています 恐らくデストラクタが走る前に動いていたスロットだと思うのですが そのせいで破棄されたクラスのオブジェクトにアクセスしようとしてセグ落ちが発生しているのだと思います ふわふわした情報で申し訳ありません... クラスが破棄されると同時に、動作中のスロットも停止させることはできないのでしょうか? よろしくお願いします 追記 -- 情報が少なく言葉足らずで申し訳ありません... 分かった情報などをまとめさせた頂きます * 該当スロットはデストラクタが走る前に、呼び出されたもの * 該当スロットではループの処理をしている、ループ中にデストラクタが走っています * ループ処理内では`QEventLoop`と`QTimer::singleShot`を使ったスリープを使って1秒間隔で処理するようにしてある(個人的にはコレが何か問題を起こしているのかと思っております) * 該当スロットのループ内とデストラクタにログを仕込みましたが、デストラクタのログ後にループのログが確認できているので、デストラクタ後にも動き続けていると判断しました * 回答に頂いたので、`this`のアドレスをログで出力させたのですが、デストラクタ後に該当スロットループ内のログでセグ落ちが発生しました、破棄された`this`へのアクセスのせいだと思われるので、私が考えている問題は起きていると思われます * ループ内でローカル変数へのアクセスは問題が起きませんが、メンバ変数へのアクセスをするとセグ落ちが発生します ここまで書いて、あることに気付いたのですが そもそもセグ落ちしている関数はスロット内で呼ばれているprivateメンバ関数です... 実質スロットの処理ではあるとは思いますが一応情報だけでも... また何か状況が変わらないかと思い`emit`で該当スロットとコネクトしてあるシグナルを呼び出していたところを、`QTimer::singleShot`で動作させてみたのですが状況は変わりませんでした
回答: 既に回答の通り、通常のQtの使い方をしている分には、オブジェクトの破棄後にそのオブジェクトのスロットが呼ばれる、ということはありえません。 もし発生しているとすれば、通常の使い方をしていないということです。例えば以下のような点に問題はありませんか? * 他のスレッドのオブジェクトが、該当のオブジェクトのポインタや参照を持っている(所有権管理違反) * 他のスレッドから AutoConnection を使わず DirectConnection でそのスロットにつないでいる * スロットをメンバー関数として直接呼んでいる * スレッドの止め方がマニュアル通りでない また、運が良ければ、静的解析ツールや valgrind などのメモリ解析ツールを使うと手がかりが得られる場合もあります。 追記へ 要するにこういうことでしょうか? ``` SomeObject::slotA() { ......前の処理...... ループ { QEventLoop loop; connect(1秒の単発タイマー → loop の quit); loop.exec(); ......次の処理...... ← ここで発生 } } ``` 「QEventLoop を使ってスリープする」というのは間違った使い方です。 QEventLoop を呼ぶと、スロットが実行中にも関わらず、同じスレッドに属するあらゆるオブジェクトのあらゆるスロットを呼ぶことが可能になってしまいます。この状況で SomeObject が delete されないように厳密に管理することは極めて困難です。「気をつけて設計すればいい」という問題ではありません。 基本的に QEventLoop をスロットの中で呼ぶのはNGだとお考え下さい。 もしチームで開発しているのでしたら、コーディング規約で禁止することをお勧めします。 正しくは、例えば次のようにします。 ``` SomeObject::slotA() { ......前の処理...... connect(1秒の単発タイマー → slotB); return; } SomeObject::slotB() { ......次の処理...... if (必要であれば) { connect(1秒の単発タイマー → slotB); } } ``` このようにすればタイマーで待っている最中に this が delete されても問題ありません(少なくともセグフォが発生しないという点については) なお、Qt 5 以降なので、スロットの代わりにラムダを使うこともできます。「ラムダとは何か?」から説明するのは大変なので、興味がお有りであればご自分でお調べ下さい。