2

これは正常にコンパイルされます。

class dummy {
};

これは、_sbrk への未定義の参照について不平を言っています:

class dummy {
    virtual ~dummy();
};

仮想メソッドが への未定義の参照を生成するのはなぜ_sbrkですか?

私はそれvtableがどこかに静的に割り当てられ、必要ないと思っていmallocました。

コンパイラ:arm-none-eabi-gcc 8.0.0最近のnewlib. でコンパイル-fno-rtti -fno-exceptions -fno-unwind-tables

テストプログラム (bootのようなものmain):

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

class dummy : public base {
public:
  ~dummy();
};

base::~base() {
  __BKPT();
}

dummy::~dummy() {
  __BKPT();
}

extern "C" void _sbrk() {
  __BKPT();
}

void boot() {
  for(;;) {
    base b;
    dummy d;
  }

  return 0;
}
4

3 に答える 3

-1

仮想関数の使用により、「純粋仮想関数」への呼び出しの例外をスローするコードのパスが取り込まれたため、_sbrk が呼び出されていることはほぼ確実です。

ルートが見つかるまで、マップ ファイルを調べて、_sbrk を呼び出しているもの、それを呼び出しているものなどを確認します。

詳細については、この投稿を参照してください: 抽象クラス (純粋仮想メソッド) を宣言すると、バイナリ サイズが大幅に増加します

ps vtables は動的メモリ割り当てを必要としません

于 2017-08-19T22:51:42.790 に答える
-2

vtable はどこかに静的に割り当てられ、malloc は必要ないと考えていました。

どこからその仮定を得たのかわかりません:

  • vtables がどのように実装されるかについての保証はありません。また、vtables を使用して動的ディスパッチを実装する必要があると標準が述べているわけでもありません。あくまでも最も一般的な方法です。
  • デストラクタ_sbrkvirtual

そして、質問の目的が本当にわかりません。仮想メソッドを使用する場合は、とにかく動的メモリ割り当て関数が必要です。

于 2017-08-19T13:16:00.207 に答える