6

奇妙な問題が発生しています。ある程度追跡できましたが、まだ原因がわかりません。たぶん、誰かがここに光を当てることができますか?

PPCgnu604 ツールチェーンを使用して C++ で開発している VxWorks 5.5 上で PowerPC プロセッサを実行しています。

私は次のようなクラスを持っています:

class MyClass
{
  public:
    void run( void );
  private:
    CommandMesssageClass command;
    StatusMessageClass status;
};

アプリケーションが開始されると、MyClass のインスタンスが動的に割り当てられ、「実行」関数を指すスレッドが生成されます。基本的に、コマンドをポーリングするだけで、受信時にステータスが返されます。

これはクラスの切り詰められたバージョンであることに注意してください。簡潔にするために、他の多くのメソッドと変数が省略されています。

コマンド メッセージとステータス メッセージの両方がプライベート クラス メンバーとして定義されている場合、動的なメモリ割り当てがないにもかかわらず、メモリ内の使用可能なバイト数が変化するという問題が発生します。これは、決定論的でレートセーフな手順である必要があるもので発生しているため、重要です。

メッセージ宣言の 1 つまたは両方を run 関数に移動すると、追加の割り当てなしで正常に動作します!

C++ の宣言とメモリ割り当てを理解する上で、何か基本的なことが欠けているに違いありません。私の理解では、動的にインスタンス化するクラス インスタンスは、作成時にヒープ (すべてのメンバー変数を含む) に完全に割り当てられます。ここでわかる違いは、メッセージ宣言を実行関数に移動すると、代わりにそれらがスタックに置かれることです。この場合のヒープは、クラス全体のサイズに対応するのに十分な大きさです。特定の部分が使用されるまで十分なメモリが割り当てられていないように見えるのはなぜですか?

メッセージ クラスは、独自の動的割り当てを行いません。(もしそうなら、宣言を移動してもこの場合の動作は変わらず、ヒープのサイズはまだ変化していると思います。)

メモリ割り当てを監視するために、次の VxWorks memLib (または memPartLib) 呼び出しを使用しています。

memPartInfoGet( memSysPartId, &partitionStatus );
...
bytesFree = partitionStatus.numBytesFree;

編集:

明確にするために、MyClass オブジェクトは初期化ルーチンでインスタンス化および初期化され、その後、コードはレート セーフ処理に入ります。この間、シリアル ラインを介してコマンド メッセージを受信すると (コマンドまたはステータス メッセージ オブジェクトとの最初のやり取り)、追加のメモリが割り当てられます (むしろ、空きバイト数が減少します)。動的メモリ割り当ては決定論的ではないため、これは悪いことです。

説明したようにクラス変数を移動することで、問題を取り除くことができました。

4

1 に答える 1

2

C++ の宣言とメモリ割り当てを理解する上で、何か基本的なことが欠けているに違いありません。

私はそうは思わない。上記で期待していることはすべて正しいです。ゲーム プログラマーは常にこの動作に大きく依存しています。:-)

特定の部分が使用されるまで十分なメモリが割り当てられていないように見えるのはなぜですか?

簡潔にするために、クラスの内臓を省略しました。私は同様の問題をデバッグした経験がいくつかありますが、私の最良の推測では、ライブラリ関数のどこかで、実際に、あなたが知らないランタイム割り当てを行っているということです。

つまり、ランタイム割り当てはどちらの場合にもありますが、MyClass の 2 つの異なるサイズは、malloc プールが異なる方法で満たされることを意味します。オブジェクトを run() 内のスタックに移動することでこれを証明できますが、MyClass を同じサイズにパディングします。それでも空きメモリのドロップが見られる場合は、それらのオブジェクトがヒープにあるかスタックにあるかとは関係ありません。これは、MyClass のサイズが原因で発生している二次的な影響です。

malloc は分厚いことを思い出してください。ほとんどの実装では、malloc の呼び出しごとに 1 対 1 の割り当ては行われません。代わりに、メモリを過剰に割り当ててプールに保持し、必要に応じてそれらのプールを拡張します。

私はあなたのツールチェーンに精通していませんが、組み込みシステムでの予期しない小さな割り当ての典型的な疑いには、ctype 関数 (ロケール) と日付/時刻関数 (タイム ゾーン) が含まれます。

于 2010-08-18T07:41:00.313 に答える