0

カスタムの new 演算子を使用してヒープ オブジェクトを作成する場合、次のnewように演算子をオーバーロードする必要があることはわかっています。

void* operator new(size_t size, int unused)
{
    void* ptr = malloc(size);
    //some custom code
    return ptr;
}

そして、このオーバーロードされた演算子を使用してヒープ オブジェクトを作成する場合は、次のようにします。

SomeClass* a = new(0) SomeClass;

問題は、スタック オブジェクトを作成するためにこのようなことを行うことができるかどうかです。

4

2 に答える 2

2

おそらくこれは必要ないが、できるという他の回答に同意します。以下のサンプル コードを参照してください。事前にメモリを割り当てて、placement new に渡します。次のようなことを行う可能性のある配列 new[] フォームを使用している場合は、これを実行することをお勧めします。

void *rawMemory = operator new[](25*sizeof(std::stack));

スタックの配列がある場合は、リソースなどを管理するファクトリ メソッドがありました。いずれにしても、アプリケーションとユースケースによって異なります。以下に簡単な例を示します

  #include <iostream>
#include <stack>

int main ( int argc, char *argv[])
{
  void *rawMemory = operator new(sizeof(std::stack<unsigned int>));
  std::stack<unsigned int> *s = new (rawMemory) std::stack<unsigned int>;

  s->push(10);

  std::cout << s->top() << std::endl;

  return 0;
}

配列バージョンを使用した 2 番目の例。25 の異なるスタックを管理し、それらをクライアントに渡す可能性がある場合に便利です。また、コメントへの返信。今回はコンテナがスタック定義で定義されていることを確認してください。この場合、コンテナにベクトルを使用しています。スタックはコンテナーですが、デフォルトで deque になるコンテナーが基礎にあります

#include <iostream>
#include <stack>
#include <vector>

int main ( int argc, char *argv[])
{
  typedef std::stack<unsigned int,std::vector<unsigned int> > StackType;

  void *rawMemory = operator new[](25*sizeof(StackType));

  StackType *stacks = static_cast<StackType*> (rawMemory);

  // allocate
  for ( unsigned int i = 0; i < 25; ++i )
  {
    new (stacks+i) StackType;
  }

  stacks[1].push(10);
  std::cout << stacks[1].top() << std::endl;

  // don't forget to delete or smart resize
  for ( int i = 24; i >= 0; --i )
  {
    StackType x;
    std::swap ( x, stacks[i] );
  }

  return 0;
}
于 2013-08-18T08:57:42.767 に答える
1

次のようなマクロを定義できます。

#define STACK_NEW(T) new (alloca(sizeof(T))) T

これは、 placement newを使用alloca()してスタックにブロックを割り当て、その上に型のオブジェクトを構築しますT。配列のバージョンを定義することもできます:

#define STACK_NEW_ARRAY(T, n) new (alloca(n * sizeof(T))) T

このマクロは、次の方法で使用します。

int * p = STACK_NEW(int);
MyObj * q = STACK_NEW(MyObj) (my, constructor, parameters);
int * r = STACK_NEW_ARRAY(int, 42);

これらのオブジェクトを手動で破棄する必要があります。

q->~MyObj();

それらを削除すると、未定義の動作が発生します。

警告: この施設全体は非常に危険です。このような体系的に危険なツールをコードベースに含めないよう強くお勧めします。私が見る限り、それを安全に使用する方法はなく、痛みを引き起こします!

于 2013-08-18T09:03:22.007 に答える