簡體   English   中英

在多線程程序中使用動態數組的頭段是否安全?

[英]Is it safe to use head segment of dynamic array in a multi threaded program?

當我們在C / C ++中定義動態數組時,它使用頭段來跟蹤數組(在堆中)中元素的數量。 例如 :

int* mem = new int[8];

編譯器將分配sizeof(int)* 8字節。

int *temp = malloc(sizeof(int)*9)

將在第一個sizeof(int)字節中存儲“ 8”,它像這樣

*temp = 8;

然后將內存地址和下一個連續地址相對於溫度

mem = temp + 1;

因此, mem將指向一個由8個元素組成的數組,而不是9個元素。

並且當刪除發生時,編譯器將使用與上述相反的過程中的mem來釋放該堆塊中的內存

delete[] mem;

我的問題是
如果我們分配一個在運行時將在不同模塊中使用的動態內存,並且設法使用分配的堆內存的頭段來檢索元素數量,那么在多線程環境中使用安全嗎?

(請假定在每個模塊中通過程序設計,沒有提供幫助函數或屬性來檢索定義的動態數組中的元素數量( 大小 )。每個模塊僅將地址(指針)傳遞給數組,但不傳遞其大小)

不,在任何環境下都不安全。 您不能依靠編譯器在分配的內存之前在數組中存儲元素數量,因為它不是定義的行為。 您永遠不要試圖達到這個值。

相反,甚至不要使用動態數組,而是選擇std::vector

訪問mem - 1具有不確定的行為。

編譯器將...

如果您以該版本的編譯器為目標,並且僅以該版本為目標,並且編譯器供應商記錄了該行為,那么也許您可以相信編譯器的版本確實如您所觀察的那樣工作。

但是,依賴於此程序的程序將不可移植到其他編譯器,也可能無法移植到同一編譯器的其他版本,也可能無法移植到使用同一編譯器的相同版本的其他平台。

這一切與多線程還是單線程無關。


如果我們分配一個在運行時將在不同模塊中使用的動態內存,並且設法使用分配的堆內存的頭段來檢索元素數量,那么在多線程環境中使用安全嗎?

在多線程程序中使用動態內存與使用任何內存一樣安全。 當然,多線程意味着潛在的數據競爭。 您必須將修改同步到其他線程可能同時訪問的任何對象。 對象是否在動態內存中沒有區別。

我使用Visual Studio發行版對此進行了測試:

int * mem = new int[8];

導致對malloc的調用等效於

int * mem = malloc(32);    // 32 = 8 * sizeof(int)

整數數組的大小不會存儲在任何地方(據我所知,包括malloc頭,malloc頭僅具有某種類型的鏈接/標志,用於重組從堆分配(並虛擬映射)的塊)。

使用未公開的系統信息原則上是毫無疑問的,即使它看起來可行:它在意外情況下的行為也可能不同,並且即使在同一制造商之間,也無法保證可移植性。

如果您還是想玩火柴,請確保在讀取大小的那一刻和訪問該塊的那一刻之間,沒有其他線程執行與內存分配相關的操作。 為此,您需要實施一個關鍵部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM