2014-07-14 54 views
5

分配函數嘗試分配所請求的數量的 存儲。 如果成功,它將返回一個 存儲塊的起始地址,其長度以字節爲單位至少大至 所請求的大小。開始塊存儲的地址

那個約束是什麼意思?你能得到一個它違反的例子嗎?

看來,我的問題還不清楚。 UPD: 爲什麼「至少」?什麼是分配點比請求的大小多?你能得到合適的例子嗎?

+3

閱讀此:http://stackoverflow.com/questions/15604411/memory-allocation-deallocation –

+0

我看到的唯一的「約束」是「如果它是成功」的情況下,我沒有看到任何「違反了」。你是否在意擴展你的意思? –

+0

@MatsPetersson查看我更新的問題 –

回答

5

分配津貼「比需要更多的」有沒有允許:

  1. 下一個數據塊的良好對齊。
  2. 減少對哪些平臺能夠運行由C和C++編譯的代碼的限制。
  3. 設計內存分配功能的靈活性。

點的一個的一個例子是:

char *p1 = new char[1]; 
    int *p2 = new int[1]; 

如果我們在用於第一分配的地址0x1000分配恰好1個字節,並按照準確地與4個字節的第二分配用於int,則int將從地址0x1001開始。這在某些體系結構上是「有效的」,但通常會導致「負載較慢」,在其他體系結構上它會直接導致崩潰,因爲在地址上不可訪問int,該地址不是偶數倍4.由於new的底層架構實際上並不知道內存最終將被用於什麼,所以最好將它分配給「最高對齊」,在大多數體系結構中這意味着8或16字節。 (如果內存用於存儲SSE數據,則需要16字節的對齊)

第二種情況是「指針只能指向32位字的整個塊」。過去有這樣的架構。在這種情況下,即使我們忽略上述對齊問題,通用指針指定的內存位置也是兩個部分,一個用於實際地址,另一個用於「該字內的哪個字節」。在內存分配器中,由於典型的分配比單個字節大得多,我們決定只使用「全字」指針,所以所有的分配都是按設計總是四捨五入到整個單詞。

例如,第三種情況是使用「預先大小的塊」分配器。例如,某些實時操作系統將擁有固定數量的預定義大小(例如16,32,64,256,1024,16384,65536,1M,16M字節)。然後將分配四捨五入到最接近的相等或更大的大小,因此將從1024大小分配257個字節的分配。這裏的想法是:a)通過跟蹤每個大小的空閒塊來提供快速分配,而不是傳統模式中的大量塊以任何大小進行搜索以查看是否有足夠大的塊。它還有助於防止碎片(當大量內存是「空閒」的時候,但是大小錯誤,因此無法使用),例如,如果運行一個循環,直到系統內存不足,分配64字節的塊,然後釋放每個其他的,並嘗試分配一個128字節的塊,沒有一個單一的128字節塊是免費的,因爲所有的內存被分割成小的64字節的部分)。

4

這意味着分配函數應返回一個內存塊的地址,其大小至少是您請求的大小。
大多數的分配功能,但是,應返回一個內存塊的大小比你要求的一個更大,直到它到達它的結束接下來的分配將返回地址這個塊的地址。
針對此行爲的主要原因是:

  1. 最小化(每個塊可以包含多個分配)的新存儲塊的分配的數量,這是在時間複雜性方面是昂貴的。
  2. 特定的對齊問題。
+0

你能看到我更新的問題嗎? –

+0

@聖安達里奧我現在可以看到它。 – eladm26

+0

@Mark你爲什麼回滾到修訂版1?你知道它確實包含語法錯誤,不是嗎? – edmz

3

爲什麼分配
返回塊比要求較大的兩種最常見的原因是

  1. 對準
  2. 簿記
2

這可能是這樣的,因爲在現代操作系統中這是很有效分配可以爲512 kb的內存頁面。所以內部的malloc功能可以只分配這個頁面的內存,在它的開始部分填入一些服務信息,關於它分成多少個子塊,它們的大小等。只有在它之後它會返回一個適合你需要的地址。下一次調用malloc將返回此分配頁面的另一部分。內存塊限制爲您要求的大小並不重要。實際上,由於沒有安全的機制來阻止這種活動,因此您可以將此緩衝區溢出。你也可以考慮其他響應者在上面陳述的對齊問題。有足夠的內存管理類型。如果您有足夠的興趣,您可以谷歌它(最適合,第一次適合,最後適合,糾正我,如果我錯了)。