1

C でメモリ アロケータを構築しようとしています。ユーザーは、使用するメモリの量と、使用できるメモリの最小ブロック サイズを指定することから始めます。

たとえば、ユーザーが最小のブロック サイズ 8B で 1024B を要求したとします。つまり、可能なブロック サイズは 1024、512、256、128、64、32、16、および 8 になります。

メモリの空きブロックを追跡するために、構造体へのポインターの配列があります。これらの構造体は Header と呼ばれ、配列は FreeList と呼ばれます。つまり、FreeList[0] には、メモリ サイズ 8 のブロックがあるメモリ内のスペースへのポインタが含まれます。FreeList[1] には、メモリ サイズ 16 のブロックがあるメモリ内のスペースへのポインタが含まれます。など

typedef void * Addr;
struct Header
{
    Addr next;
    int order;
};

struct Header *FreeList[];

次のコードで使用するために、この空きリストにメモリを割り当てようとしています。

FreeList = malloc(Order*sizeof(struct Header));

Order は、使用できるブロック サイズの数です。

コンパイル エラー 'FreeList' に不完全な型があります。

これらのポインターがどこかを指すようにしたくありません。データ用のスペースを割り当てたいだけです。

4

1 に答える 1

7

C言語で

struct Header *FreeList[];

サイズが不明な静的配列(不完全型)の仮定義です。この配列は、既知のコンパイル時のサイズで後で定義する必要があります。ポイントは、静的配列であるということです。によって「割り当て可能」ではありませんmalloc

実行時に によって割り当てることができるポインターの配列が必要な場合はmalloc、ポインターからポインターへの変数を宣言する必要があります。

struct Header **FreeList;

これは後で適切なサイズで割り当てられます

FreeList = malloc(Order * sizeof *FreeList);

この場合、必要に応じて、ポインタの配列を割り当てていることに注意してください。また、sizeof上記の割り当ての は と同等sizeof(struct Header *)です。sizeof(struct Header)つまり、ポインターのサイズです (元のコードの不適切なサイズとは対照的に)。

これも、初期化されていないポインターの配列を割り当てます。これらのポインターを初期化するのは、つまり、ポインターが指すようにしたい場所を指すようにするのは、ユーザーの責任です。必要に応じて、実際のヘッダーにもメモリを割り当てる必要があります。


ただし、ヘッダーへのポインターの配列が本当に必要なのか、実際のヘッダーの配列が必要なのかは、投稿した内容からは明確ではありません。あなたの説明は紛らわしく、時には自己矛盾しています。実際のヘッダーの配列が必要な場合、ポインターの宣言と割り当ては次のようになります。

struct Header *FreeList;
...
FreeList = malloc(Order * sizeof *FreeList);

この場合、上記の式は、元の例のようにsizeofと同等です。sizeof(struct Header)ただし、割り当てられたヘッダー配列はまだ初期化されていないことに注意してください。

于 2012-07-10T21:09:10.143 に答える