2016-08-22 17 views
-1

こんにちは私は比較的新しくCで、誰かが次のコードで何をしているのかを説明できるかどうか疑問に思っていました。構造体のシンタックスの混乱

私は構造体持っている:私の質問は、まさに私がここでやっていると理由です

typedef struct free_list_header { 
    u_int32_t magic; // ought to contain MAGIC_FREE 
    vsize_t size;  // # bytes in this block (including header) 
    vlink_t next;  // memory[] index of next free block 
    vlink_t prev;  // memory[] index of previous free block 
} free_header_t; 

と私は、以下のものを使用して、関数内でそれを初期化しています...

void vlad_init(u_int32_t size) 
{ 

    int sizePow2 = pow(2, ceil(log(size)/log(2))); 
    memory = malloc(sizePow2*sizeof(char)); 
    memory_size = sizePow2; 
    strategy = BEST_FIT; 

    free_header_t *freeHeader = (free_header_t*)memory; 

    freeHeader->magic = MAGIC_FREE; // the unique value 
    freeHeader->size = memory_size; // amount we malloc'd 
    freeHeader->next = 0;    // position of next free block 
    freeHeader->prev = 0;    // position of prev free block  
    free_list_ptr = 0; 
} 

をそれは必要ですか?

free_header_t *freeHeader = (free_header_t*)memory; 

だから私は "freeHeader"という名前を指して新しい構造体を宣言していますか?それは私が割り当てたメモリ内のポインタですか?これは、構造体をmallocされた領域に置いて、関数を初期化する関数からアクセスする方法です。

+0

あなたが書いたコード、または課題やチュートリアルの一部としてあなたに与えたコードはありますか?それは変だと感じています。同様に、構造体のサイズの代わりにcharのサイズを使用してメモリを初期化するのはなぜですか? 'memory'を最初に初期化するのではなく、' freeHeader'を直接初期化して、後でキャストで代入するのはなぜですか? – AntonH

+0

Hmmm ...用語が明確ではありませんが、それは問題の一部である可能性があります。 'sizePow2'とは何ですか?少なくともmemory_sizeと同じくらい大きい方が良いか、(おそらく)問題にぶつかるでしょう。あるいは、問題は 'memory_size'ですか?それとも両方の場合もあります。 –

+0

だから、そのメモリアロケータと初期化関数は数字をとり、少なくとも2の最小の累乗をmallocに少なくともそれほど割り当てます。 memory_size == sizePow2、私は編集し、関数全体を追加します。 – qruton

答えて

0

Mallocはvoidポインタ(型void *)を返します。つまり、メモリアドレスへのポインタを返し、ポインタが特定の型を指していないことを意味します。したがって、行の後:

memory = malloc(sizePow2*sizeof(char)); //sizePow2 is n bytes to allocate 

メモリはタイプ(void *)のポインタです。ここにあなたが明示的にキャストしているために、このポインタは型free_header_tのアドレスを指していると述べたfree_header_t のでタイプのものを含むメモリアドレスを指すfreeHeaderという名前のポインタを作成している左手側で

free_header_t *freeHeader = (free_header_t*)memory; 

もう片方の側(現在はvoid *型)がfree_header_t *と一致するようにします。

Cで、これは動作しますが、必ずしも必要ではありません。コンパイラはvoid *を必要な型に自動的にキャストします。しかし、このようなコードを書くのは良い習慣です.C++では明示的にこれを行う必要があります。

+0

*キャスト*は明示的な変換です。 'void *'型の値は暗黙的に*任意のオブジェクトポインタ型に変換されます。明示的に 'malloc'の結果をキャストするのは、Cではなく、' malloc'を使用することはC++では良いことではありません。 CとC++の両方でコンパイルされたコードを記述する必要がある場合はキャスティングが必要ですが、これはまれな要件です。 –

+0

さらに、 'memory'の宣言は質問には表示されていないので、" void * '型のポインタであることは、最善の推測です。私たちが知っている限り、 'free_header_t *'型にすることもできます。 –

+0

@KeithThompsonキャストmallocが必要** ** C&C++でコンパイルするコードを作成する場合は? – CIsForCookies

0
free_header_t * freeHeader = (free_header_t*)memory; 

あなたは、構造体freeHeaderという名前の、あなたはそれをメモリという名前のポインタの値を割り当てをfree_header_tするポインタ(ない実際の構造体)を宣言しました。メモリはcharへのポインタであり、あなたのものは他のものへのポインタであるため、キャストを使用しました。

現在、割り当て済み領域へのポインタ(サイズsizePow2 * sizeof(char) - 構造体のサイズは割り当てられたメモリのサイズ以下である必要があることに注意してください)。

free_header_t *freeHeader = malloc(sizePow2 * sizeof(char)); 

それはsizePow2バイトを含むメモリのブロックを割り当て、その後free_list_header構造のアドレスとしてそれを使用しています:

0

コードは本質的に等価です。

memory変数を使用する理由は、他のコードがnextprevのメンバーをそのメモリブロックのインデックスとして使用するためです。名前が示すように、この構造はメモリブロックの先頭にデータを格納し、残りのメモリは他の構造で管理されます。

-1
memory = malloc(sizePow2*sizeof(char)); 

ここではいくつかのメモリを割り当てています。

memory = malloc(sizeof(struct free_list_header)); 

を使用して構造体を保存するとよいでしょう。

free_header_t *freeHeader = (free_header_t*)memory; 

ここでは、先に割り当てられたメモリを指すポインタを宣言しています。あなたは構造のオブジェクトを技術的に宣言しませんでした。そして、構造体をmalloc-ed領域に置くのではなく、malloc-ed領域を構造体のオブジェクトとして扱います。

free_header_t freeHeader = {0};は、構造体のオブジェクトを宣言しています。

-1

malloc()関数を呼び出すたびに、オペレーティングシステムによって1つのメモリアドレスが返されます。このポインタを特定の型にキャストすると、割り当てられたメモリに格納されているすべての要素が指定された型のサイズを消費することがコンパイラに伝えられます。

uint64_tとそのサイズをuint64_tの100倍とすると、uint64_tが8バイトになると、オペレーティングシステムで800バイトを要求しているとします。このポインタをキャストしないと、your_variable++でアドレスを増やすたびに、プログラムは1バイトだけスキップし、数字の真ん中に入り、奇妙な値を取得しますが、ポインタをuint64_tを使用してアドレスをyour_variable++に増やすと、プログラムは8バイトをスキップして次の番号に直接進みます。

例では、ポインタにfree_header_tの種類が格納されることをオペレーティングシステムに伝えています。あなたはそれをする義務はありませんが、それは非常に良い習慣です。

また、このアドレスを別の関数に返すと、他の関数はこのメモリ領域に格納されている値を簡単に変更できます。

希望すると助かります!