2014-06-20 44 views
-4

在C++中,使用iostream,可以打印變量的內存地址。例如:C++將內存的地址轉換爲值?

std::cout << &variable << std::endl; 
// Example Result: 002AFD84 

但是,如果我想將該內存地址存儲到變量中呢?如將內存地址轉換爲字符串或double(或int等)?或者甚至將該字符串或double(或int等)再次轉換回內存地址?

我想這樣做的各種原因,其中一個是:這將允許我將DLL中的數據的內存地址返回到調用DLL的程序和它的功能。最重要的是,我不必跟蹤DLL中的數據本身,因爲數據可以通過內存地址來引用。

由於約束條件,我無法在此特定情況下使用指針。約束條件是:我正在使用的解釋性編程語言無法訪問指針。由於這個原因,指針不能用於引用DLL之外的數據。

作爲一個側面問題,內存地址使用什麼數字格式?他們似乎總是8個字符的長度,但我無法弄清楚這是什麼格式。

+2

指針似乎是合理的。 – chris

+0

不,它沒有。我有限制,這就是爲什麼我對我所問的問題感到好奇。 – user3519915

+3

有什麼限制?通常在C++應用程序中,你傳遞的內存是作爲指針傳遞的 – JarkkoL

回答

3

如果你絕對需要這樣做,我建議選擇你轉換成什麼類型​​。任意將指針轉換爲非指針類型可能會產生問題,並引入難以檢測的問題。如果您使用reinterpret_cast執行轉換,則尤其如此。最常見的問題之一是各種平臺之間的目標類型的大小。當您使用類似reinterpret_cast的東西時,您通常不會在轉換過程中收到有關精度損失的警告。

對於需要將指針轉換爲整數類型的情況,我建議將這些轉換包裝在函數模板中。這將允許您在執行轉換時具有一定的靈活性,並且可以執行編譯時大小檢查以確保目標類型足夠大以容納指針。

類似下面的代碼可能會有所幫助。

template<class DestType, class SourceType> 
DestType bubblicious_value_cast(const SourceType& src) 
{ 
    static_assert(sizeof(DestType) >= sizeof(SourceType), "Destination size is too small"); 
    return reinterpret_cast<DestType>(src); 
} 

int main() 
{ 
    void* ptr = nullptr; 
    int val = bubblicious_value_cast<int>(ptr); 
} 
3

可以使用reinterpret_cast這樣的:

uintptr_t address = reinterpret_cast<uintptr_t>(&variable); 

在64位(或32位)的環境中的存儲器地址有64位(32位)的長度,分別。

+1

這是一種非常快速的方式,可以使用典型的64位系統丟失一半的地址。 – chris

+1

'uintptr_t'至少會自動適當的大小。 –

+0

謝謝,我忘了64位系統。 – so61pi

3

要將指針轉換爲字符串表示形式,可以使用字符串流。這些與標準I/O流std::cinstd::cout類似,但寫入或讀取字符串而不是執行I/O。

std::ostringstream oss; 
oss << &variable; 
std::string address = oss.str(); 

要的指針轉換成表示同一地址的整數,使用reinterpret_castuintptr_t類型(如果存在)保證足夠大以容納任何指針值。但我認爲通常使用unsigned long就足夠了。

unsigned long address = reinterpret_cast<unsigned long>(&variable); 

將指針轉換爲浮點類型似乎相當無用。您必須首先轉換爲整型,然後從那裏轉換爲浮點型。

+0

現在使用reinterpret_cast我可以將地址作爲一個整數來檢索,但是,如何將該整數轉換回內存地址? – user3519915

+0

@ user3519915使用另一個'reinterpret_cast'回到指針類型。 – Brian

+0

例如,像這樣? 'type * Pointer = reinterpret_cast (Address);' – user3519915