2

私はCortexM3用のARMツールセットでKeil4を使用しています(それが重要な場合でも)。私はこの単純なコードを試しました:

class Base
{
    public:
    virtual ~Base() {}
};

class Derived : public Base
{

    public:
    int b;

    virtual ~Derived() {}
};

ローカル(メイン内)でDerivedのインスタンスを作成すると、すべてが正常になります。デバッグは機能し、プログラムサイズは約300バイトです。

Derivedの静的またはグローバルインスタンスを作成すると、プログラムサイズが最大1000バイト増加し、BKPT命令でデバッグセッションが停止します。

これは、ヒープサイズがデフォルト値(ゼロ)に設定されているためです。ヒープを追加すると、デバッグが機能し始めました。

デストラクタを保護しますが、仮想ではない場合、同じ動作になります。通常のメソッドを仮想化することはしませんでした。

だから、私の質問は:この状況でコンパイラがヒープを必要とする理由は何ですか?

Vtabは静的に作成され(チェックしました)、グローバルオブジェクトも静的である必要があります。動的割り当てが必要ない場合、ヒープ割り当てコード(およびヒープ自体のスペース)にさらに700バイトを浪費するのはちょっとばかげています。

(警告を防ぐためにデストラクタを仮想化しました。)

4

2 に答える 2

1

インスタンスが関数の外部で定義されている場合、2つのことが起こります。まず、mainが呼び出される前に、オブジェクトのコンストラクターが呼び出されます。プログラマーは、コンストラクターが後で発生する初期化を必要とする可能性のあることを何もしないように注意する必要があります。次に、mainの前にローカルスコープがないため、インスタンスのメモリがヒープに割り当てられます。組み込みシステムのプログラマーは、グローバルオブジェクトのインスタンス化に特に注意する必要があります。コンストラクターがmainの前に初期化されていないハードウェアに依存している場合、悪いことが起こる可能性があります。Keilが提供するCスタートアップファイル(ヒープの初期化後にmainを呼び出し、flashをramにコピーし、グローバルコンストラクターを呼び出すアセンブリ言語モジュール)をよく理解してください。

于 2013-07-01T16:34:11.020 に答える
1

答えはここ、Keilフォーラム-http ://www.keil.com/forum/21859/にあります。その理由は、メインから戻った後に呼び出される生成された関数「__aeabi_atexit」です。このリターンは組み込みシステムでは決して起こらないので、これはちょっと面白いです。

于 2013-07-03T12:48:02.597 に答える