簡體   English   中英

以下語句是否將物理地址或虛擬地址分配給指針?

[英]Do the following statements assign either physical or virtual address to a pointer?

https://stackoverflow.com/a/2761494/156458

C和C ++都沒有提供嚴格定義的功能,該功能不允許您將特定的物理地址分配給指針。 因此,您有關“如何將0地址分配給指針”的問題正式沒有答案。 您根本無法為C / C ++中的指針分配特定的地址。 但是,在實現定義的功能領域中, 顯式的整數到指針的轉換旨在實現這種效果。 因此,您可以按照以下步驟進行操作

 uintptr_t address = 0; void *p = (void *) address; 

請注意,這與執行操作不同

 void *p = 0; 

后者總是產生空指針值,而前者通常不會。 前者通常會產生一個指向物理地址0的指針,該地址可能為也可能不是給定平台上的空指針值。

我很驚訝地發現void *p = 0並沒有分配物理或虛擬地址0,而是將空指針void分配給了指針。

引號還說,“顯式整數到指針轉換”可以為指針分配地址。

問題:

  1. void *p = 0 ,是否存在從0void*隱式轉換?

    隱式轉換是否與顯式轉換(void *)0 ,即void *p = 0void *p = (void*) 0嗎?

    void *p = (void*) 0產生指向物理地址或虛擬地址0的指針或void的空指針?

  2. 如果我使用非零數字,例如void *p = 123 ,是否存在從123void *隱式轉換?

    隱式轉換與顯式轉換(void *) 123嗎?

    void *p = 123void *p = (void *)123會使p指向物理或虛擬地址123的指針嗎?

    如果void *p = (void *)123無法生成指向物理或虛擬地址123的指針,則可以int addr = 123; void *p = (void *)addr; int addr = 123; void *p = (void *)addr; 我通過在引用的第一個示例中將int替換為unitptr_t創建它。

謝謝。

如果你說

char *p = 0x12345;

您可能會分配p指向地址0x12345 無論是虛擬地址還是物理地址,我們都不能說。 這取決於您的計算機及其配置。 (但是,如果您的計算機使用虛擬內存,並且正在編寫普通的用戶程序,那么它肯定是虛擬地址。)

在上面我說“大概”,部分原因是嚴格來講,為指針分配整數並不明確。 為了安全起見,您應該寫

char *p = (char *)0x12345;

同樣,這將分配p指向地址0x12345

但是接下來我們來談談特殊情況。 如果你寫

char *p = 0;

要么

char *p = (char *)0;

問題是,您是否已分配p指向地址0 答案可能是在任何傳統機器上,但這不能保證,因為空指針存在特殊情況。

不是說p = 0 不會分配p指向地址0 ,而是可能不會 在空指針的內部表示形式不是全零的機器上,分配p = 0會將p設置為該空指針值,因此p 不會指向地址0。

TL; DR:您所要求的大部分是特定於實現的行為和語言擴展領域。 如果您確實需要這種行為,請查閱編譯器文檔。

  1. void *p = 0 ,是否存在從0void*隱式轉換?

初始化是不合格的,但是許多編譯器都接受它作為擴展。 那些確實定義了所需結果的人,但實際上,它們確實提供了對void *的隱式轉換。

因為文字0是“空指針常量”,因為初始化程序執行與簡單賦值相同的轉換,並且因為簡單賦值為將空指針常量賦值給指針提供了特殊情況,所以, 0被隱式轉換為void * 此外,因為0是空指針常量,所以這種轉換會導致類型為void *的空指針。

隱式轉換是否與顯式轉換(void *)0 ,即void *p = 0void *p = (void*) 0嗎?

有充分的理由期望接受前一種形式的編譯器將與后一種形式完全相同,但是同樣,前者是不合格的,並且將其接受為擴展名的實現為其定義了自己的語義。

是。 C無處可區分通過強制轉換和相同類型之間的自動轉換顯式指定的轉換效果。

void *p = (void*) 0產生指向物理地址或虛擬地址0的指針或void的空指針?

它初始化p包含一個空指針(類型為void * )。 根據C,空指針不會指向任何對象,並且C除了對象或函數的地址之外沒有任何地址意義,因此至少在這種意義上,將此類指針解釋為指向任何特定地址是不正確的。 取消引用這樣的指針的效果不是由C定義的,而是可以由某些實現定義的-可能試圖訪問地址0的對象。

  1. 如果我使用非零數字,例如void *p = 123 ,是否存在從123void *隱式轉換?

該初始化不符合要求,但是某些編譯器提供了隱式轉換作為擴展。

隱式轉換與顯式轉換(void *) 123嗎?

有很好的理由期望編譯器完全實現這種隱式轉換,但同樣要實現“擴展”。

void *p = 123void *p = (void *)123會使p指向物理或虛擬地址123的指針嗎?

那是實現定義的。 同樣,C除了對象或函數的地址之外,沒有其他意義的地址,特別是它本身拒絕指定將整數轉換為指針類型的結果,除了首先通過將指針轉換為整數而獲得的整數外,對於值為0的整數常量表達式。

但是,在某些實現中,將整數(值為0的整數常量除外)轉換為指針具有將整數解釋為地址,並轉換為指向該地址的指針的效果,就像存在一個帶有該地址的對象一樣地址。 托管 C實現中,這通常是虛擬地址。 獨立實現中,它通常是物理地址。 一些實現方式也可以將此行為擴展為值為0的整數常量,該常數可能或可能不是固有地不一致。

如果void *p = (void *)123無法生成指向物理或虛擬地址123的指針,則可以int addr = 123; void *p = (void *)addr; int addr = 123; void *p = (void *)addr; 我通過在引用的第一個示例中將int替換為unitptr_t創建它。

完全有理由期望,顯式轉換值為123的int變量的結果與顯式轉換值為123的整數常量的結果完全相同,但是從技術上講,它是實現定義的,可能為編譯器提供了遵循的空間。區分。

暫無
暫無

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

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