0

unsigned char* headメモリ内の特定のアドレスを指しているaがあり、そのポインタの位置から開始して宣言したtypedef構造体を作成する必要があります...その方法について混乱しています!

これがtypedefの宣言です

 typedef struct {
    struct block *next;
    struct block *prev;
    int size;
    unsigned char *buffer;
} block;

私の割り当てにはmallocの実装が含まれているため、mallocを使用できません。ブロックは、プログラムヒープにある空きメモリブロックのすべてのチャンクを含むfree_listの一部です。したがって、メモリの前の空きブロックと次の空きブロックを指す前と次のポインタ。

ヘッドはfree_listの先頭を指します。空きメモリの最初のブロックを分割して、その空きブロックよりも必要なスペースが少ないmalloc()要求を満たす必要がある場合は、頭を動かしてそこに新しいブロック構造体を作成する必要があります。

これが理にかなっていることを願っています。そうでない場合、割り当ては次のようになります

4

4 に答える 4

1

構造体にはタグがないため、構造体がそれ自体を指すようにするには、タグを付ける必要があります。

 typedef struct block {
    struct block *next;
    struct block *prev;
    int size;
    unsigned char *buffer;
} block;

headC99を使用している場合は、一時的なものを宣言せずに、必要に応じて直接メモリを初期化できますstruct block

*(block *)head = (block){NULL, NULL, 0, NULL};

適切にキャストする限りstruct block、アドレスにがあります。head

例えば

((block *)head)->size = 5;

または、それにキャストポインタを割り当てます。

block *p = (block *)head;
p->size = 5;
于 2013-03-23T22:44:53.690 に答える
0

コメントから:

headデータを上書きできるメモリ内の場所の開始点を指します...十分なスペースがあると思われるかもしれません。

次に、適切に型指定されたポインタを取得するには、次のようにします。

struct block *p = (struct block *)head;

ブロックのコピーを作成するには:

struct block b = *(struct block *)head;
于 2013-03-23T22:28:02.047 に答える
0
unsigned char* head = /* whatever you have assuming that it has a sufficient size. */;

/* Create a block in memory */
block* b = (block*)malloc(sizeof(block));

/*
*   modify data in b here as you wish.
*/
b->next = 0;
b->prev = 0;
/* etc... */

/* copy b to head */
memcpy(head, b, sizeof(block));

/* free block */
free(b);

上記は、headにブロックのインスタンスを格納するのに十分なスペースがあることを前提としています。ブロックを作成し、メモリをヘッドの位置にコピーしてから、割り当てられたブロックを解放します。

于 2013-03-23T22:22:01.537 に答える
0

オペレーティングシステムは、API呼び出しを提供して、切り分けて呼び出し元に提供できるメモリのブロックを割り当てますmalloc。Linux / unixでは、を見てくださいsbrk。Windowsでは、Win32ヒープAPIを確認してください。あなたの記録はこのブロックを指します。ブロックの2つの割り当てられたセクションが重複しないようにすることは、アロケータコードの仕事です。

あなたの記録は無料のリストを実装しているようです。では、アロケータが(まだ)ない場合、リストノードをどのように割り当てるのでしょうか。通常の解決策は、空きブロック自体でそれを行うことです。したがって、フリーブロックの構造は次のとおりです。

typedef struct free_block {
    struct free_block *next, *prev;
    size_t size;
    unsigned char buffer[1];
} FREE_BLOCK;

現在、このデータ構造は実際には空きブロックの先頭にあります。そのバッファの宣言には1バイトしかありませんが、実際のバッファはsizeバイトです。最初は次のようなものがあります。

static FREE_BLOCK *free_list = sbrk(ARENA_SIZE);
free_list->next = free_list->prev = free_list;
free_list->size = ARENA_SIZE - offsetof(FREEBLOCK, buffer);

これにより、アリーナ全体が1つのブロックとしてフリーリストに追加されます。アロケータはfree_list、十分な大きさのブロックを検索し、必要な部分を切り分け、残りの小さなブロック(存在する場合)をフリーリストに戻します。解放するために、解放されたブロックをリストに追加し、隣接するブロックを合体させます。

単純なフリーリストアロケータは、割り当てるフリーブロックの選択方法が異なります。ファーストフィット、ローテーションファーストフィット、ベストフィット、ワーストフィットなどです。実際には、ローテーションファーストフィットは他のどのブロックよりもうまく機能するようです。

ちなみに、フリーリストで実装される一般的なアルゴリズムはすべて、二重リンクを必要としません。単一のもので十分です。

これは学術的な課題であるためmalloc、アロケータが管理する大きなブロック(「アリーナ」と呼ばれることが多い)を確立するために(オペレーティングシステムAPIの代わりに)呼び出すだけで問題ありません。バイトの大きな配列を宣言することもできます。

于 2013-03-23T22:36:14.300 に答える