我將Mat數據(不是cv :: Mat對象)傳遞給一個函數,並使此函數成爲此數據的新所有者。但是,我需要一種方法來釋放原始對象,而不釋放它指向的數據緩衝區。免費cv ::墊沒有釋放內存
我知道這將發生在從外部數據創建的cv :: Mat中,我只需要將這個特性用於常規cv :: Mat。
有沒有辦法做到這一點?
我將Mat數據(不是cv :: Mat對象)傳遞給一個函數,並使此函數成爲此數據的新所有者。但是,我需要一種方法來釋放原始對象,而不釋放它指向的數據緩衝區。免費cv ::墊沒有釋放內存
我知道這將發生在從外部數據創建的cv :: Mat中,我只需要將這個特性用於常規cv :: Mat。
有沒有辦法做到這一點?
您可以使用addref()
方法,但是您將有內存泄漏。
其實它不是從墊分離的數據是個好主意:
那麼只有兩種方式墊保證支持:
任何其他方式可以在未來的版本中打破,即使它在當前工作。
USE 釋放()
PTR
http://opencv.willowgarage.com/documentation/cpp/basic_structures.html
模板類智能引用計數指針
template<typename _Tp> class Ptr
{
public:
// default constructor
Ptr();
// constructor that wraps the object pointer
Ptr(_Tp* _obj);
// destructor: calls release()
~Ptr();
// copy constructor; increments ptr's reference counter
Ptr(const Ptr& ptr);
// assignment operator; decrements own reference counter
// (with release()) and increments ptr's reference counter
Ptr& operator = (const Ptr& ptr);
// increments reference counter
void addref();
// decrements reference counter; when it becomes 0,
// delete_obj() is called
void release();
// user-specified custom object deletion operation.
// by default, "delete obj;" is called
void delete_obj();
// returns true if obj == 0;
bool empty() const;
// provide access to the object fields and methods
_Tp* operator ->();
const _Tp* operator ->() const;
// return the underlying object pointer;
// thanks to the methods, the Ptr<_Tp> can be
// used instead of _Tp*
operator _Tp*();
operator const _Tp*() const;
protected:
// the encapsulated object pointer
_Tp* obj;
// the associated reference counter
int* refcount;
};
類PTR < _TP>是一個模板類包裝相應類型的指針。它與Boost庫(http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/shared_ptr.htm)的一部分shared_ptr類似,也是C++ 0x標準的一部分。
通過使用這個類,你可以得到以下功能:
default constructor, copy constructor and assignment operator for an arbitrary C++ class or a C structure. For some objects, like files, windows, mutexes, sockets etc, copy constructor or assignment operator are difficult to define. For some other objects, like complex classifiers in OpenCV, copy constructors are absent and not easy to implement. Finally, some of complex OpenCV and your own data structures may have been written in C. However, copy constructors and default constructors can simplify programming a lot; besides, they are often required (e.g. by STL containers). By wrapping a pointer to such a complex object TObj to Ptr<TObj> you will automatically get all of the necessary constructors and the assignment operator.
all the above-mentioned operations running very fast, regardless of the data size, i.e. as 「O(1)」 operations. Indeed, while some structures, like std::vector provide a copy constructor and an assignment operator, the operations may take considerable time if the data structures are big. But if the structures are put into Ptr<> , the overhead becomes small and independent of the data size.
automatic destruction, even for C structures. See the example below with FILE* .
heterogeneous collections of objects. The standard STL and most other C++ and OpenCV containers can only store objects of the same type and the same size. The classical solution to store objects of different types in the same container is to store pointers to the base class base_class_t* instead, but when you loose the automatic memory management. Again, by using Ptr<base_class_t>() instead of the raw pointers, you can solve the problem.
類PTR把被包裝的對象作爲一個黑盒子,引用計數器分配和單獨管理。指針類需要知道的唯一對象是如何釋放它。這些知識被封裝在Ptr :: delete_obj()方法中,當引用計數器變爲0時,該方法被調用。如果對象是C++類實例,則不需要額外的編碼,因爲此方法的默認實現調用delete obj; 。但是,如果以不同的方式釋放對象,則應該創建專門的方法。例如,如果你想換文件時,delete_obj可以實現如下:
模板<>內嵌無效PTR :: delete_obj(){ FCLOSE (OBJ); //之後不需要清除指針, //它是在外部完成的。 } ...
//現在使用它: PTR F(的fopen( 「myfile.txt的」, 「R」)); if(f.empty()) throw ...;如果(f.empty()) throw ...; fprintf(f,....); ... //該文件將由Ptr析構函數自動關閉。
注意:引用遞增/遞減操作是作爲原子操作實現的,因此在多線程應用程序中使用類通常是安全的。對於在參考計數器上運行的Mat和其他C++ OpenCV類也是如此。
您可以使用lambda捕獲Mat,並且可以使用此lambda作爲刪除器來擴展和限制其生命到shared_ptr/unique_ptr。
Mat matrix;
...
std::shared_ptr<uchar*> ptr(matrix.ptr(),[matrix](uchar*){});
它有用,當你不想使用OpenCV的您的公共接口上,你不能提供您的指針放在墊創建或不想將數據複製到緩衝區。
//遞減參考計數器;當它變爲0時,// delete_obj()被調用--- *在我描述的情況下調用release會刪除對象,這樣被調用的函數將獲得釋放的內存* –