2017-05-01 20 views
1

私はいくつかのコードを持っていますが、それは動作します、なぜ私は理解しません。ここをクリックしてください:このポインタ逆参照の例はなぜ機能しますか?

// This structure keeps the array and its bookkeeping details together. 
typedef struct { 
    void** headOfArray; 
    size_t numberUsed; 
    size_t currentSize; 
} GrowingArray; 

// This function malloc()'s an empty array and returns a struct containing it and its bookkeeping details. 
GrowingArray createGrowingArray(int startingSize) { ... } 

// Self-explanatory 
void appendToGrowingArray(GrowingArray* growingArray, void* itemToAppend) { ... } 

// This function realloc()'s an array, causing it to double in size. 
void growGrowingArray(GrowingArray* arrayToGrow) { ... } 

int main(int argc, char* argv[]) { 
    GrowingArray testArray = createGrowingArray(5); 

    int* testInteger = (int*) malloc(1); 
    *testInteger = 4; 

    int* anotherInteger = (int*) malloc(1); 
    *anotherInteger = 6; 

    appendToGrowingArray(&testArray, &testInteger); 
    appendToGrowingArray(&testArray, &anotherInteger); 

    printf("%llx\n", **(int**)(testArray.headOfArray[1])); 

    return 0; 
} 

これまでのところ、すべては私が意図したとおりに動作します。私を混乱させる部分は、次の行です。

printf("%llx\n", **(int**)(testArray.headOfArray[1])); 

私の理解では、printf()の第2引数は意味をなさないものです。私は主に試行錯誤している。構造体のポインタの配列の2番目の要素がintへのポインタへのポインタであると私は言っているように私に読んでいます。そうではありません。これは単なるintへのポインタです。私にメイクセンスを何

はこれです:

*(int*)(testArray.headOfArray[1]) 

これは、構造体に含まれるポインタの配列の2番目の要素は最後の括弧によってフェッチされるというのが私の理解だ、と私はそのそれを整数へのポインタとしてキャストし、そのポインタを逆参照してください。

私の理解に間違っていますか?コンパイラはこれをどのように解釈していますか?実際に矢を育てるために追加のロジックで

void appendToGrowingArray(GrowingArray* growingArray, void* itemToAppend) { 
    growingArray->headOfArray[growingArray->numberUsed++] = itemToAppend; 
} 

明らかにかかわら:

+0

デザインが間違っています。 'headOfArray'は' void * 'でなければなりません。 ** appendToGrowingArray(&testArray、&testInteger);を呼び出す必要もあります。** appendToGrowingArray(&testArray、&testInteger); – user3528438

+1

'* testInteger = 4;'は1バイトだけ割り当てました –

+1

'**(int **) (testArray.headOfArray [1]) 'はおそらく未定義の振る舞いであり、間違ったprintfフォーマット指定子を使用しています。より良い答えを得るには、MCVEを投稿していないコードには未知のものがたくさんあります。 –

答えて

0

私の最高の推測では、あなたのappendToGrowingArrayは次のようになりますということです。しかし、ポイントは、itemToAppendheadOfArrayが指す配列に格納されている点です。

しかし、あなたはappendToGrowingArray通話を見れば、あなたはアドレスtestIntegeranotherIntegerを渡している - これらはすでにあるが、整数へのポインタなので、あなたが本当にしようとするとき、あなたはあなたのheadOfArrayの整数へのポインタへのポインタを格納しています整数へのポインタを格納する。

あなたがtestArray.headOfArray[1]を考えるときに、それは値が変数anotherIntegermainのスタック上のアドレスあるのです。最初に参照解除すると、anotherIntegerに格納された2番目のmalloc呼び出しによって返されたバッファのアドレスを指すようになります。だから、それはあなたがそれを欽慕する場合にのみ、あなたがそのバッファの内容に着く二度目だ、つまり数6

はおそらく書きたい:

代わり
appendToGrowingArray(&testArray, testInteger); 
appendToGrowingArray(&testArray, anotherInteger); 

(コメントに記載されているように、mallocを修正する必要があります。最近は整数を格納するために1バイト以上必要です)

関連する問題