[Transfer] http://hi.baidu.com/maxint/blog/item/fc817c2f29881f331e3089ef.html
1. Security pointer
Since opencv2.0, many C data structures have changed to C ++ classes. Considering compatibility, the old APIs are retained. In terms of memory management, a secure pointer PTR is provided, so that the old data structure (iplimage, cvmat, etc.) that requires manual memory management does not require manual release. Its usage is as follows:
Ptr<IplImage> img = cvReadImage("Lena.jpg");
PTR is a template class, which is defined as follows in opencv:
template<typename _Tp> class Ptr{public: Ptr(); Ptr(_Tp* _obj); ~Ptr(); Ptr(const Ptr& ptr); Ptr& operator = (const Ptr& ptr); void addref(); void release(); void delete_obj(); bool empty() const; _Tp* operator -> (); const _Tp* operator -> () const; operator _Tp* (); operator const _Tp*() const;protected: _Tp* obj; int* refcount;};
The source code definition above adds a refcount to the original pointer class and reloads some operators (operator-> ;()). It is worth noting that the PTR template has a requirement on the object pointed to by the pointer, that is, the delete operation can be used to release the memory. You may think that iplimage does not meet this requirement. What should you do? You can use template specialization to overload the PTR <iplimage>: delete_obj () function:
template<> inline void Ptr<IplImage>::delete_obj(){ cvReleaseImage(&obj); }
2. pointer alignment (http://bytes.com/topic/c/answers/213142-what-pointer-alignment)
Why do we need pointer alignment? This is because in some architectures, only memory addresses that can be divisible by a specified number (such as 4 or 16) can be accessed. Otherwise, the program will crash or cause an error, or Data Access slows down. For example, many systems require the interger address to start from an even number. In opencv2.0 or later versions, many pointers are aligned so that the pointer address can be divisible by 16. The memory in opencv is generally allocated through malloc, which cannot be guaranteed to be fully divided by 16. In this case, it needs to be truncated. But how should we maintain the remaining memory? This is maintained by cv2.0: When malloc is used to apply for a pointer space, this pointer points to the real memory address obtained by malloc, only in
Use it for free. Related functions:
Typedef unsigned char uchar; # define cv_malloc_align 16 template <typename _ TP> static inline _ TP * alignptr (_ TP * PTR, int n = (INT) sizeof (_ TP )) {return (_ TP *) (size_t) PTR + N-1) &-N) ;}__ declspec (dllexport) void * fastmalloc (size_t size) {uchar * udata = (uchar *) malloc (size + sizeof (void *) + cv_malloc_align ); // here apply for a void * space for storing udata uchar ** aData = alignptr (uchar **) udata + 1, cv_malloc_align); aData [-1] = udata; // <-store udata return aData; }__ declspec (dllexport) void fastfree (void * PTR) {If (PTR) {uchar * udata = (uchar **) PTR) [-1]; Assert (udata <(uchar *) PTR & (uchar *) PTR-udata) <= (ptrdiff_t) (sizeof (void *) + cv_malloc_align); free (udata );}}