3
class MyString
{
  public:
  MyString(int length):_ptr(alloca(length))
  {
  }
  //Copy Constructor, destructor, other member functions.
  private:
  void* _ptr;
};

int main()
{
  MyString str(44);
  return 0;
}

main関数の最後で解放されますか、それともコンストラクターが実行された直後に解放されますか?上記のコードが期待どおりに機能する場合は、このような文字列クラスを作成することをお勧めしますか?

アップデート:

主な危険は

  1. スタックオーバーフロー
  2. コンストラクターのインライン化

小さいサイズの場合はallocaを使用し、大きいサイズの場合はmalloc / freeを使用することで、StackOverflowを処理できると思います。コンパイラを強制的にインライン化するには、移植性のないコンパイラ固有の方法が必要だと思います。

文字列クラスはあらゆるc++プロジェクトで広く使用されているものなので、私は興味があります。これを正しく行うと、ほとんどの割り当てがスタック内に配置され、そうでない場合はヒープに入るので、パフォーマンスが大幅に向上することを期待しています。これはユーティリティであり、エンドユーザーは内部を認識しません。

4

2 に答える 2

5

allocaのドキュメントによると、allocaの呼び出し元が戻ったときにメモリが解放されます。したがって、初期化子リストがコンパイラーによってコンストラクターの一部と見なされる場合、つまり、初期化リストが実行される前にスタックフレームが作成される場合、メモリーはコンストラクターの最後で解放されます。イニシャライザリストの実行後にスタックフレームが作成された場合、割り当てられたメモリはコンストラクタの呼び出し元にあるため、この場合、メモリはmainの最後で解放されます。私はそれがどのように起こるかを絶対的に確信するのに十分な基準を知りません。

ただし、ptrメモリが最終的に解放されるたびに、の値は変更されません。

于 2011-11-02T11:41:22.647 に答える
3

間違いなく、クラスメンバーの初期化はc'torの一部として実行されます。したがって、少なくとも標準では、によって返されるポインタの有効性はallocac'torに制限されます。

したがって、クラスメンバーを自分のやり方で初期化するのは本当に悪い考えのようです。

OTOH以下は問題ありません。

class MyString
{
  public:
  MyString(void* ptr):_ptr(ptr)
  {
  }
  //Copy Constructor, destructor, other member functions.
  private:
  void* _ptr;
};

int main()
{
  MyString str(alloca(44));
  return 0;
}
于 2011-11-02T12:16:55.787 に答える