2016-10-09 73 views
0

當前正在學習C++,我正在重新訪問一個小內存管理器,我們的教授已經部分編寫爲練習,因爲我忽略了C++技能太久,我遇到了問題了解新實際記憶和放置的實際效果。所以基本上我有多個Bucket對象,它們都包含一定數量的塊,並且每個塊都可以有一定量的內存。 BucketAdmin類包含所有這些Bucket對象。瞭解C++中的內存訪問與新的放置位置

BucketAdmin::BucketAdmin(void) 
{ 
m_baseMemory = reinterpret_cast<unsigned char *>(malloc(sizeof(Bucket) * NUM_OF_BUCKETS)); 

Bucket* base_pointer = reinterpret_cast<Bucket*>(m_baseMemory); 
std::cout << &base_pointer<< "  " << &base_pointer + sizeof(Bucket) *  NUM_OF_BUCKETS << "  " << sizeof(Bucket) * NUM_OF_BUCKETS << std::endl; 

for (unsigned short i = 0; i < NUM_OF_BUCKETS; i++) 
{ 
    m_buckets[i] = new (&base_pointer[i])Bucket(m_bucketSizes[i], BUCKET_CAPACITY/m_bucketSizes[i]); 
} 
} 

所以這段代碼在這裏讓我很困惑。一個桶的大小是16字節(正如sizeof(Bucket)所指出的那樣,並且桶的數量是5.這意味着m_baseMemory分配80字節的ram並且是一個char指針(reinterpret_cast的工作原理是什麼以及它爲什麼使用兩次接下來,通過將內存地址從之前的地址轉換爲Bucket指針創建一個存儲桶指針 - 這是如何以及爲什麼是這樣的?當我輸出兩個地址時,它們彼此非常不同。行是分配了80個字節的內存,其地址保存在m_baseMemory中,然後,因爲我們要構造Bucket對象,該指針被轉換爲Bucket指針,這樣我們就可以遍歷for-循環(基本上一個i是i * sizeof(Bucket)的偏移量,所以i * 16,正確嗎?)沒有具體說明每個Bucket對象所需的偏移量

因此, ew正在& base_pointer [i]的位置使用,它們不應該是相同的嗎?我不明白這兩種內存地址(m_baseMemory,base_pointer)是如何大相徑庭的。當我將base_pointer地址與base_pointer地址加上分配的內存進行比較時,我應該得到一個大於80的地址(十進制),但是當我比較數字時,它會有幾百個之差?一個例子: 的base_pointer ADRESS是:010FFA6C 的base_pointer ADRESS +的sizeof(剷鬥)* NUM_OF_BUCKETS是:010FFBAC

即使的sizeof(剷鬥)* NUM_OF_BUCKETS = 80將被解釋爲十六進制,這將增加128(8 * 16),而不是這裏的情況。我真的不明白這是如何計算的,所以幫助將不勝感激。

謝謝。

+0

對齊需求可能? 'Bucket'需要對齊,而'char'不需要。 –

+0

16字節?你確定它不是16位(2字節),因爲這會使更多的感覺更加合理嗎? –

+0

@TomaszPlaskota sizeof返回16,所以我猜這意味着16個字節,不是? – Grougal

回答

1

混淆的主要原因是您在查看base_pointer的地址時應該查看其值。

您似乎錯過的另一件事是,將k添加到指針將地址添加到k + sizeof(what the pointer points to)

&base_pointer是您的變量的地址,而不是分配的內存,所以&base_pointer + sizeof(Bucket) * NUM_OF_BUCKETS是一個地址80 * sizeof(Bucket*)字節遠離它。
80 * sizeof(Bucket*)在32位目標上是320。

您感興趣的地址是base_pointer; m_baseMemory + k * sizeof(Bucket)base_pointer + k表示相同的地址,&base_pointer[k]也是如此。

+0

謝謝,這給了我一些信息。 但爲什麼m_baseMemory和base_pointer仍然如此不同?我猜這跟Cast對象的指針有關,但它究竟是如何工作的?我的意思是,它不能把地址分割成Bucket的大小或類似的東西,因爲這會完全改變地址。 – Grougal

+0

此外,如果我輸出m_baseMemory(這是一個字符指針,鍵入char *)我得到奇怪的符號,而不是一個地址。那是怎麼回事?它不應該像base_pointer一樣工作,它們都指向大致相同的地址? – Grougal

+1

@Grougal試圖澄清。 (如果要打印它,請將一個指針指向'void *')。 – molbdnilo