2012-03-06 21 views
2

在C++中有一種方法可以檢查內存地址是否被任何指針引用?C++:檢查一個地址是否被引用

+0

你是指什麼內存地址?一個對象將佔用一系列的地址,指針只會指向開始。你想說'我有這塊內存地址,想知道系統中有沒有對象嗎? – 2012-03-06 07:49:19

回答

8

不,完全沒有。

(除非你做的顯然跟蹤自己。)

+0

簡短,簡單,重要! – Marlon 2012-03-06 06:58:30

+0

對於「追蹤你自己」,可能是不可行的,或者更好的「不與計劃指針」。 雖然你可以替換新的/刪除來查看分配的內容,直到有可能做指針分配和算法的「跟蹤」風險不成功(因爲有操作可以繞過它) 這是可能的(在類似C的方式)在普通地址上實現Hans Bohem算法,但不可能正確銷燬對象。 C++的方式應該需要一個垃圾收集指針類與垃圾收集新的(手有一個禁用刪除)合作 – 2012-03-06 07:34:34

2

這將意味着C++有一個垃圾收集器或等價物,它沒有。換句話說,不。

你可以利用智能(尤其是共享這個用例)指針來管理你的內存。

+0

是的...我明白智能指針是一個選項...我的項目是一個大的組成1000s的文件...用智能計數器部件替換所有的指針是簡單的不合理的...只是想檢查我們是否有任何其他方法來做到這一點...... Thx! – rahul 2012-03-06 06:57:28

1

這是不可能的。考慮指針算法:從給定的記憶位置,你可以增加你的方式,併到達不同的位置。這是用於跨陣列移動:從

int * a = &array[0]; 

沒有人知道,如果你會做++ A,A + 3,或什麼的。你可以從數組[0]開始,超出數組邊界(這是沒有界限的,實際上是:-))。

這是深深根植於C和C++繼承它,但C++已經開發了一系列的慣用風格,試圖儘量減少需要去原始指針級別。你可以閱讀關於智能指針(保持指向給定資源的人數並在計數變爲零時將其刪除)的智能指針。在很多情況下,你可以使用std :: vector而不是數組,而不必考慮超出數組末尾的風險。

+0

這不是真正的原因。 C編譯器可以將每個對象的詳細信息放在一起並將其傳遞給運行時,以便可以計算可達的所有對象的集合。你會知道每個指針在哪裏隱藏,然後你可以檢查它們是否指向給定的地址。對於越界指標也是如此。如果我們可以遍歷所有的數據並且到達這個變量'a'並且知道它是一個指針,我們可以將它與一個給定的地址進行比較。但是,唉,我們沒有那個信息。 – Kaz 2012-03-06 07:43:18

+0

我不確定要理解你的推理:假設你有一個指針,並且你動態計算一個偏移量並將指針指向新的位置。當然,這將在系統爲您的流程分配的空間中,但是如何在不設置其他位置的書籍管理機器(本質上是垃圾收集器)的情況下知道?這是可能的,但與C方式(原始指針和手動內存管理)以及C++方式(智能指針,RAII,標準libray容器)非常不同。 – Francesco 2012-03-06 10:09:12

0

在執行此操作之前,您需要實現自己的智能指針,動態內存分配或垃圾回收器。

+0

你不需要自己實現它,因爲stdlib中有智能指針。不要重新發明輪子,除非你的觀點是重新發明輪子。 – Griwes 2012-03-06 07:08:27

+1

好的,但不確定是否可以問他們是否有指針指向它們。 – Damian 2012-03-06 07:15:22

+0

那麼,你的智能指針將爲每個可尋址字節創建一個大表,併爲每個可尋址字節存儲指針計數器?我不這麼認爲。要檢查地址是否指向某個東西,以及這個「有多少東西」在那裏,你將不得不訪問智能指針對象。跟蹤指向給定字節的指針而不在智能指針中檢查它會太大而無法使用。一般來說,您只需將內存管理留給智能指針並使用它們來控制內存 - 無需將計數器存儲在外。 – Griwes 2012-03-06 07:30:27

0

不是。但是......


Boehm Garbage Collector非常成功地管理由悲觀這樣做,是考慮到任何東西,看起來像一個內存地址內存地址(而不是位域的一個隨機整數或繼承這恰好看起來如此)。悲觀意味着某些數據的收集時間比以前要晚得多,但這對於垃圾收集器來說並不重要(並且要比收集太快!)。


在C++ 11,已經引入了一些low-level facilities緩解垃圾收集器的創建:

  • declare_reachable:聲明的對象不能被回收

  • undeclare_reachable:聲明可以回收物件

  • declare_no_pointers:聲明的存儲區域不包含可追蹤的指針

  • undeclare_no_pointers:取消的std::declare_no_pointers

  • pointer_safety效果:列表指針安全模型

  • get_pointer_safety:返回當前指針安全模型

declare_no_pointers暗示對象只包含整數/ bitfi elds/whatever和no指針,這樣在掃描垃圾收集器時可能會更準確。這種知識可能會影響你的情況。


然而,這一切都墮入包裝技巧的。例如,通常利用64位指針具有太多位並使用其中的一些來在指針內存儲標誌的事實。或者相反,利用有效載荷來存儲指針或整數值。顯然,掃描存儲器尋找指針時,這並不好,因爲掃描的值與實際地址不一致。

這些技巧在Clang/LLVM或Javascript引擎(V8,SpiderMonkey等)中大量使用,例如,以及一些真正關心內存佔用空間和速度的軟件。


所以,總的來說,沒有C和C++太寬鬆記憶準確地能夠知道。即使std::shared_ptr不超過約定,並且可能會意外地在其他地方存儲原始指針

實際上,對於您可能遇到的大多數問題都有解決方案。無論是使用類型系統和一些約定,或使用Boehm的掃描(這應該是非常罕見的...)。然而,這需要更詳細的問題。

相關問題