2

アプリケーションにグローバルスタックを作成し、このスタックに特定のオブジェクトを配置したいと思います。これらのオブジェクトは固定サイズではありません。

私は現在持っています。

static char contextStack[CONTEXT_MAX_SIZE];
static char *top = &contextStack[0];

new継承された基本クラスの演算子をオーバーライドします

static void *operator new(size_t size) {
  void *Result;
  Result = top;
  top = top + size;
  return Result;
};

delete問題は、スタックからポップする演算子をどのように実装するかです。アイテムの大きさはわかりませんか?各エントリのサイズを配列に格納する必要がありますか?

(ps)最後に作成されたものが常に最初に削除されます。そして、スタックに準拠しています。

4

4 に答える 4

2

各エントリのサイズを配列に格納する必要がありますか?

別のストレージ領域を使用することも、実装がよく従う戦略を使用することもできますmalloc。実装は、返されるポインターの前の既知の場所にサイズを格納します。を呼び出すとfree、渡したポインタの直前の場所を確認し、そこからサイズを取得して、割り当て解除を続行します。

あなたの場合、チャンク自体の直後にチャンクのサイズをプッシュすることができます。スタックをポップするときは、最初にサイズをポップしてから、データチャンクをポップします。

スタックを操作するときに注意する必要があることの1つは、データアライメントです。アーキテクチャによっては、マルチバイトタイプを奇数オフセット(4、8などで分割できないオフセット)に格納すると、パフォーマンスの低下やバスエラーが発生する可能性があります。プラットフォームの詳細をチェックして、スタックにプッシュされた連続する要素の間に余分な「パディング」を導入する必要があるかどうかを確認する必要があります。

于 2012-07-08T11:33:12.130 に答える
1

この場合、メモリを処理するためのさまざまなオプションがあります。メモリを昇順で返す場合(これが当てはまるようです)、サイズを覚えておく必要はありません。割り当てられた最後のメモリブロックは、割り当てられたポインタからtopまでであり、渡されるポインタとしてtopを設定するだけでdelete十分なので、算術演算を実行する必要はありません。

(スタックで一般的なように)降順でメモリを割り当てていた場合は、スタック自体にサイズを格納できます。ポインタ演算を実行して新しいResulttop - requested_size)を取得し、次にデクリメントsizeof(int)し、そこにサイズを格納して、topポインタをそのポインタに設定します。

プラットフォームの配置制限に注意する必要があります。プラットフォームですべてのデータ型への調整されていないアクセスが許可されている場合でも、パフォーマンス(およびスレッドセーフ)の理由からデータを調整することをお勧めします。

于 2012-07-08T11:40:34.607 に答える
1

スタックを作成するためにテンプレートクラスを使用する場合、各アイテムのサイズを知る必要はありません。はるかに簡単です。

于 2012-07-08T12:03:44.600 に答える
0

スタックを処理するときのアセンブリの経験から言えば、コードがスタックから何かをポップしたい場合、そのコードは、その何かがどれだけ大きいか、または予想されるかを知る責任があります。スタックは、連続したデータの巨大なチャンクであり、技術的には、必要な大きさのデータがそこにある限り、それを取り除くことができます。

したがって、コードはオブジェクトの大きさを事前に知る必要があります(あなたが持っていないように見える情報)。もちろん、サイズを配列に格納するという提案など、他のさまざまな方法で「スタック」を実装することもできます。そうすることで、スタックを持つことの単純さがさらに複雑になりますが、実装で必要になる場合があります。

于 2012-07-08T11:32:26.217 に答える