1

誰かが私のスタックベースのアロケータを手伝ってもらえますか?

static char Stack[MAX_SIZE];
static char *top = &Stack[0];

class STACKED {
    public:
        static void *operator new(size_t size) {
            //Add this context to the context stack.
            void *Result;
            assert( (top + size) <= &Stack[MAX_SIZE] );

            Result = top;
            top = top + align_sizeof(size);
            return Result;
        }

        static void operator delete(void *p) {
            //Its a stack, and delete only removes the top entry.
            // So *p represents where to delete to.
            top = (char *)p;
        }

        static size_t align_sizeof(size_t object_size) {
            // TODO: Align objects.
            return object_size;
        }
};

1)スタックがオーバーフローするかどうかを検出するためのアサートは正しいですか?

2)align_sizeof()-パフォーマンス/バスの問題のためにこれらのオブジェクトを整列させたい。しかし、私はアライメントを完全には理解していません。誰かがメモリアライメントを説明し、スタックオブジェクトをアライメントする式を提案できますか?

2a)私の現在の考えは、オブジェクトのサイズを「切り上げ」て、上部が常に整列するようにすることです。必要以上のメモリを効果的に割り当てます(最後にパディングを配置します)。

3)静的文字スタック[MAX_SIZE]も整列する必要があると思います-これを行うにはどうすればよいですか?

ありがとうございました!

PS他のコメントはいつでも歓迎します

4

1 に答える 1

0

まず 、配列名は最初の要素へのポインターであるため、 にstatic char *top = &Stack[0];置き換える ことができます。static char *top = Stack;

あなたのコードは非常に安全ではありません。配列内の要素へのポインターを返しています。accert は問題ありませんが、次のような使用法を検討してください。

STACKED a;
char * foo = (char *)a.operator new(10);
foo += 10000000;
*foo= 's';

これによりクラッシュが発生し、アサートはこれを助けません。

メモリを管理したい場合は、配列をクラス内に配置し、クラスにすべての使用を処理させ、ユーザーが直接ポインターを操作できないようにする必要があります。このような場合、ユーザーが非結合インデックスにアクセスしたいかどうかを追跡できます。

オブジェクトを削除するときは、スタックの一番上だけを移動するべきではありません。ユーザーがスタックの「中間」にあるアイテムを削除しようとする場合は、スタックの状態を適切に変更する必要がありますが、既に割り当てられているメモリへのポインターを台無しにしないように注意してください。

アライメントについては、 wikiをチェックしてください。それが役立つことを願っています。

また、要素を削除するときは、取得したポインターが実際にスタック内のどこかを指していることを確認する必要があります。悪いコードの例を次に示します。

STACKED a;
char * foo = new char(10);
a.operator delete(foo - 10000);
char * crash = (char *)a.operator new(10);

assert() この場合は助けになるかもしれませんが、クラスのユーザーは実際に何が起こったのか理解できないかもしれません。

于 2012-07-09T07:58:24.843 に答える