2013-06-19 66 views
1

這是一個關於正確使用手柄的非常基本的問題。考慮下面的代碼(這是不是一個特定的源文件):手柄如何正確管理?

typedef void* HANDLE; 

HANDLE myHandle; 

myHandle = SomeObject; 

//...some elaborate code...// 
  1. 第一個問題:是myHandle現在位於堆棧或堆?由於Handle可以是一個指針,也可以只是一個索引,所以我不太確定。

    在myHandle超出範圍的地方,它被刪除(至少我認爲是這樣)。但是,如果它是一個類成員,它將保持可見,直到擁有的對象被刪除。所以第二個問題:

  2. 如果我想避免myHandle任何進一步的訪問,是很好的做法做

    myHandle = 0; // I do not need this handle anymore 
    

    請問我碰到內存管理衝突,現在,或關於管理的任何其他限制碼?是否有其他的選擇來說明這把手不宜使用了類似指針:

    mypointer = NULL; 
    

編輯:我說的是排在首位的垃圾收集這顯然是不包括在C++。這是managed extensions的一部分。感謝您幫助我解決這個致命的錯誤!

+1

「指針和索引」? 「垃圾收集器刪除」?這裏發生了什麼......也許從一開始就開始。這個問題沒有道理。 –

+2

首先,我強烈建議您閱讀有關C++內存管理的更多內容,因爲C++中沒有垃圾收集器。如果你指的是WinAPI句柄,你應該在完成它們之後在句柄上調用CloseHandle(句柄)。但是,你應該研究C++內存管理,否則你將會遇到更嚴重的麻煩。 – Kourosh

+0

爲什麼*沒有答案提示RAII?給我一個值得加強的答案! – jalf

回答

1

您可能是來自您所做假設的Java程序員。

變量myHandle確實分配在堆棧上,當它超出作用域時被刪除,雖然不是由垃圾收集器(C++中不存在這種情況)。

不過,這並沒有免費手柄(myHandle只是擁有一些不透明的數值,在實際手柄由OS擁有的變量 - 所以它的壽命是不相同的任何壽命任意變量保存該值)。您必須使用適當的API函數(對於大多數情況是HANDLE,這是CLoseHandle)自己執行此操作,最好使用「句柄持有者」類,因此它是異常安全的。

一個簡單的實現這樣一個手柄保持架看起來是這樣的:

class AutoHandle 
{ 
    HANDLE handle; 
public: 
    AutoHandle(HANDLE in) : handle(in) {} 
    ~AutoHandle() { CloseHandle(handle); } 
}; 

這樣,你打開一個資源時,分配給AutoHandle變量,當它超出範圍,手柄是關閉。你不能忘記這麼做,如果發生異常,它甚至可以工作。

1

由於您尚未指定您正在討論的是什麼HANDLE,我假定Windows處理。

A HANDLE是一個不透明的數據類型(主要表示操作系統可以使用的數字),並且應該僅通過系統函數來處理,例如CreateFileCloseHandle

您不應該在丟失關聯資源時自行設置HANDLE0

請參閱CloseHandleCreateFile(特別是返回值)和Windows Data Types

Wikipedia

In computer programming, a handle is an abstract reference to a resource. Handles are used when application software references blocks of memory or objects managed by another system, such as a database or an operating system.

While a pointer literally contains the address of the item to which it refers, a handle is an abstraction of a reference which is managed externally; its opacity allows the referent to be relocated in memory by the system without invalidating the handle, which is impossible with pointers. The extra layer of indirection also increases the control the managing system has over operations performed on the referent. Typically the handle is an index or a pointer into a global array of tombstones.


和C++沒有通過標準垃圾收集,這就是爲什麼你需要刪除new編輯自己的對象,而不是處理由系統給定的!

0

通常更傾向於在將指針指向NULL之前使用delete。

但是對於一個HANDLER不要把它放到NULL自己!