2012-10-07 131 views
1

我知道null(0x00000000)是指向沒有,因爲操作系統不允許進程在這裏分配一個內存。但是如果我使用0x00000001(魔術數字或代碼指針),那麼操作系統不會允許在此處分配也很安全? 如果是,那麼它停在哪裏?C++ - 安全指針範圍?

+4

我不明白一個單詞 – axis

+0

@axis我們使用null是因爲我們不想指向任何東西。但是,如果我想指向1類似null的東西。但有一點不同。還可以嗎?如果是,那麼它停在哪裏? ...現在沒事了? – DividedByZero

+0

所以你想要一個無效的指針,但以不同的方式使用空指針。從設計角度來看,這看起來很奇怪。這將是interessting理解你爲什麼要這樣做... – ElektroKraut

回答

4

標準(第一)

標準只能保證0是一個標記值儘可能指針走。底層的內存表示無法得到保證;它的實現已定義。

使用指針設置爲別的比讀指針狀態或寫一個新的狀態標記值(包括非關聯或指針運算)是未定義的行爲

虛擬內存

在虛擬存儲器的天數(即,每一個進程獲取其自己的內存空間,獨立於其他人),一個空指針是在該過程的存儲空間最經常的確表示爲0 。實際上我不知道其他架構,但我想在大型機中可能不是這樣。

的Unix

在Unix世界中,這是典型的保留所有下面爲0x8000的地址空間爲空值。內存未被分配,實際上,它只是受保護(即,放置在特殊模式下),以便操作系統在嘗試讀取或寫入時會觸發分段錯誤。

使用這種範圍的想法是空指針不一定按原樣使用。例如,如果使用std::pair<int, int>* p = 0;爲空,並調用p->second,則編譯器將執行指向second(即,一般爲+4)所需的算術,並嘗試直接訪問0x4上的內存。這個問題顯然是由數組加起來的。

實際上,這個0x8000限制應該足夠實用以檢測大多數問題(並避免內存損壞或其他問題)。在這種情況下,這意味着您可以避免未定義的行爲並獲得「正確」的崩潰。但是,如果你使用的是大陣列,你可能會超調它,所以它不是銀彈。

您的實現或編譯器/運行時堆棧的特定限制可以通過文檔或通過連續試驗來確定。甚至可能有一種方法來調整它。

+0

那麼windows \ linux有什麼限制? – DividedByZero

+0

@DividedByZero:我不知道Windows,不要在那裏編程。在Linux上,它將取決於你的發行版。你需要檢查所有的平臺和所有你關心的工具鏈。這就是實現定義的含義。 (它可能在所有主流Linux上都是「0x8000」,但不要聽我的話) –

1

唯一有效的範圍應該是由OS分配給您的範圍。除此之外,其他操作應該被操作系統拒絕。

該規則的一個例外是共享內存。

2

你不應該假設任何關於指針的實際值。尤其是,空指針是而不是需要用零地址表示,儘管文字0看起來像零。

+0

那麼你的意思是說有一種方法可以在0x00000000處分配內存? – DividedByZero

+1

爲什麼你甚至在意在某個特定地址分配某些東西? – fredoverflow

+0

我不在乎,我想使用另一個地址,如0到其他地方。但我關心如果可以分配內存。 – DividedByZero

1

C++標準不會「保留」除零(空)以外的任何指針地址。因此,使用1或任何其他值作爲「魔術」指針值是不安全的。當然,在實踐中,C++的某些實現可能並不是每個都使用某些值。但是你沒有從語言定義中得到任何保證。

0

我會盡量給廣泛瞭解這個:

  1. 你可能永遠不會訪問,因爲每一個現代操作系統有和地方提出了多沙盒機制的實際存儲器地址。
  2. 什麼是軟件觀點的NULL指針?一個NULL指針是一個指針變量,它存儲一個值,程序員選擇這個值作爲一個有意義的值,這個值被用作一個標籤,其含義如下:「這個指針無處可去」。一個NULL指針根據定義不指向0x000000,NULL指針的定義與它指向的指針的位置無關,但該宏的值被調用爲NULL,並且此值將是此NULL指針的值。
  3. 用C可以假定NULL == 0,只在C NULL是一個宏NULL定義爲int等於0,在C++中,沒有這個自由
  4. 有類型,標籤和值(在更好的術語,值的表示,而不是真正的值),對於每個變量,至少對於基元值來說,指針是一樣的,如果你正在談論關於空指針的問題,你正在談論包含內存地址的指針(就像任何指針一樣)關於這個指針的唯一特別之處在於它們需要在C++中進行強制轉換才能被安全有效地解碼。這是一個很大的錯誤,如果你想void*作爲指針指向無處或0NULL0x0000000

順便說一下,我還是不明白你的問題......

0

一現代操作系統可能至少爲NULL指針保留一頁。所以0x1(或0x4如果你想32位對齊)很可能工作。

但請記住,這不能由C/C++語言保證。你將不得不依賴於你的操作系統和編譯器的這種行爲。

此外,不能保證NULL指針的實際值。它可能或可能不全是零。如果不是這樣,你的伎倆根本不起作用。