pofeiren0 2014-10-30
OpenCV使用内存存储器(memory storage)来统一管理各种动态的内存。内存存储器在底层被实现为一个有许多相同大小的内存块组成的双向链表,通过这种结构,OpenCV可以从内存存储器中快速的分配内存或将内存返回给内存存储器。
--------------------------------------分割线 --------------------------------------
--------------------------------------分割线 --------------------------------------
1.数据结构
cvMemStorage结构体定义
typedef struct CvMemStorage
{
int signature;
CvMemBlock* bottom; /* First allocated block. */
CvMemBlock* top; /* Current memory block - top of the stack. */
struct CvMemStorage* parent; /* We get new blocks from parent as needed. */
int block_size; /* Block size. */
int free_space; /* Remaining free space in current block. */
}
CvMemStorage;
内存存储器是一个用来存储诸如序列,轮廓,图形和子划分等动态增长数据结构的底层结构.它由一系列同等大小的内存块构成,呈列表型.其中,bottom域指列首,top域指当前指向的块,但未必是列尾.在bottom和投票之间的所有块空间(包括bottom,但不包括top)被完全占据;在top和列尾之间所有的块空间(包括列尾,但不包括top)则是空的;而top块空间本身则被部分占据.free_space指top块内剩余的空字节数.
新分配的内存缓冲区(显示的通过函数cvMemStorageAlloc分配,或隐式地通过高级函数cvSeqPush和cvGraphAddEdge等分配)总是起始于当前块(即top块)中剩余的那部分空间,但前提条件是剩余的部分有足够大小的分配空间.分配后,free_space就减少了新分配的那部分内存大小,以及一些用来保存适当类型的附加大小.当top块的剩余空间无法满足被分配的块(缓冲区)大小时,top块的下一个存储块被置为当前块(新的top块),而free_space被置为先前分配的整个块的大小.
如果已经不存在空的存储块(即top块已是列尾),则必须再分配一个新的块(或从parent那里继承,见函数cvCreatChildMemStorage)并将该块加到列尾上去.于是,存储器(memory storage)就如同栈(stack)一样,bottom指向栈底,(top, free_space)对指向栈顶.栈顶可通过函数cvSaveMemStoragePos保存,通过函数cvRestoreMemStoragePos恢复指向,通过函数ClearStorage重置.
CvMemBlock结构体定义
typedef struct CvMemBlock
{
struct CvMemBlock* prev;
struct CvMemBlock* next;
}
CvMemBlock;
CvMemBlock代表一个单独的内存存储块结构.内存存储块中的实际数据存储在header块(即一个以头指针head指向的块,该块不存储数据)之后,于是,内存块的第i字节可以通过表达式((char*)(mem_block_ptr+1))[i]获得.然而,通常没必要直接获得存储结构的域.
CvMemStoragePos结构体定义
typedef struct CvMemStoragePos
{
CvMemBlock* top;
int free_space;
}
CvMemStoragePos;
此结构保存栈顶的地址.栈顶可以通过函数cvSaveMemStoragePos保存,也可以通过函数cvRestoreMemStoragePos恢复.