0

私は自分のもののインスピレーションとしてそれを使用して、いくつかのコード(実際にはArduPilot)を調べています。今、私は重大なバグを見つけたと思います - しかし大声で叫ぶ前に ;) 誰かが私が C++ を誤解していないかどうかをチェックするのを手伝ってくれるかもしれません.

方法があります(私はそれを単純化しました):

void GCS_MAVLINK::update(void) {
    // receive new packets
    mavlink_message_t msg;
    mavlink_status_t status;

    // process received bytes
    while (data_available()) {
        uint8_t c = receive_data();
        // Try to get a new message

        if (parse_and_accumulate(c, &msg, &status)) {
            handleMessage(&msg);
        }
    }
}

これは定期的に呼び出されます。使い果たされるまでバッファからデータを読み取り、最終メッセージへの参照とステータス構造体とともに外部解析関数にスローして、副作用によって更新します。パーサーがメッセージの完了を確認するたびに、メッセージが消費されます。

ここまでは順調ですね。メッセージの途中でバッファが空になるとどうなりますか? OK、残りはおそらく次のスケジュールされた呼び出しでバッファに到着します。しかし、割り当てられたローカル/スタックはどうなりますか!!! メッセージとステータス変数? 私の知る限り、その間にスタックの使用によるあらゆる種類のごみで上書きされた可能性があります。スタック ポインタがシフトした可能性さえあります。

私が馬鹿にする前に、ここに大きな問題があるように見えることを誰かが確認するのを手伝ってくれませんか..

また、msg 変数と status 変数を静的にして「修正」しても、それらはメソッドを含むクラスのインスタンスごとに別々になりますよね?

よろしくソレン

4

3 に答える 3

3

メッセージの途中でバッファが空になるとどうなりますか?

おそらく、parse_and_accumulateメッセージの準備が整うまで、出力メッセージパラメーターとは別に、着信バイトをどこかに保存することになっています。そうである場合にのみ、そのパラメーターに書き込みます。その関数が呼び出し間でメッセージ オブジェクトが保持されると想定している場合にのみエラーが発生し、関数を確認せずに判断する方法はありません。

しかし、割り当てられたローカル/スタックはどうなりますか!!! メッセージとステータス変数?

あなたが言うように、関数が終了するとそれらは破棄されます。それらを永続的なストレージとして使用した場合 parse_and_accumulate、それらは永続的ではないため、バグがあります。そうならないことを願っていますが、そうなった場合、その仮定はほぼ確実に修正されるべきものです。

また、msg 変数と status 変数を静的にして「修正」しても、それらはメソッドを含むクラスのインスタンスごとに別々になりますよね?

それらを作成してstaticも何も修正されません。再入不可であるため、おそらくあいまいなバグが発生するだけです。表示されていない機能が間違っている場合は、それを修正する必要があります。

それらをstatic(ローカル変数またはクラスメンバーとして)作成すると、それぞれのインスタンスは1つだけになります。それらを永続化し、オブジェクトに関連付ける必要がある場合は、非静的クラス メンバーにする必要があります。しかし、ほぼ確実にそうすべきではありません。

于 2012-12-18T11:25:20.500 に答える
0

私が馬鹿にする前に、ここに大きな問題があるように見えることを誰かが確認するのを手伝ってくれませんか..

問題がある場合とない場合があります。あなたが示したコードだけで伝えることは本当に不可能です。

メッセージの途中でバッファが空になるとどうなりますか? OK、残りはおそらく次のスケジュールされた呼び出しでバッファに到着します。

バグがあると主張する前に、これが実際に発生する可能性があることを確認する必要があります。あなたが示しているコードはこれに対処するために書かれているようには見えませんが、そうする必要はないのでしょうか?

また、msg 変数と status 変数を静的にして「修正」しても、それらはメソッドを含むクラスのインスタンスごとに別々になりますよね?

いいえ、そうしません。また、コードが再入不可になり、スレッドセーフではなくなります。

于 2012-12-18T11:22:53.943 に答える
0

parse_and_accumulate のソースをもう一度見てみると、呼び出し間でデータ保存されていることがわかります。引数 struct は、完了したメッセージを..

だから私の悪い - 申し訳ありません。助けてくれてありがとう!

于 2012-12-19T20:51:34.837 に答える