OpenCV使用内存存储器(memory storage)来统一管理各种动态的内存.内存存储器在底层被实现为一个有许多相同大小的内存块组成的双向链表,通过这种结构,OpenCV可以从内存存储器中快速的分配内存或将内存返回给内存存储器.
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;
如果已经不存在空的存储块(即top块已是列尾),则必须再分配一个新的块(或从parent那里继承,见函数cvCreatChildMemStorage)并将该块加到列尾上去.于是,存储器(memory storage)就如同栈(stack)一样,bottom指向栈底,(top, free_space)对指向栈顶.栈顶可通过函数cvSaveMemStoragePos保存,通过函数cvRestoreMemStoragePos恢复指向,通过函数ClearStorage重置.
typedef struct CvMemBlock { struct CvMemBlock* prev; struct CvMemBlock* next; } CvMemBlock;
typedef struct CvMemStoragePos { CvMemBlock* top; int free_space; } CvMemStoragePos;
起初,创建的存储块是空的.头部header的所有值域除了block_size外均为0.
结果,在存储块中出现了垃圾(临时数据).然而,如果在开始处处理数据前就先建立一个子存储块,且将临时数据写入子存储块中并在最后释放子存储块,那么最终在源/目的存储块中就不会出现垃圾,于是该存储块看上去应该是如图4-3所示形式.
功能:
函数cvReleaseMemStorage释放内存块
格式:
void cvReleaseMemStorage(CvMemStorage** storage);
参数:
storage 指向被释放了的存储块的指针
说明:
函数cvReleaseMemStorage先释放所有的存储(内存)块或将它们返回给各自的parent(如果需要的话).然后在释放header块[释放头指针head指向的块执行语句free(head)]并清楚指向该块的指针(执行语句head=NULL).在释放parent块之前,必须先清楚各自的child块.
功能:
函数cvClearMemStorage清空内存存储块
格式:
void cvClearMemStorage(CvMemStorage* storage);
参数:
storage 内存存储块
说明:
函数cvClearMemStorage将存储块的top置于存储块的头部(注意,应清空存储块中的存储内容).次函数并不释放内存,仅清空内存.假设该内存块有一个父内存块(即存在一内存块与其有父子关系),则次函数将所有块放回给其父内存块.
功能
函数cvMemStorageAlloc在存储块中分配一内存缓冲区
格式:
void* cvMemStorageAlloc(CvMemStorage* storage,size_t size);
参数
storage 内存块
size 缓冲区大小
说明
分配的缓冲区大小不能超过内存块大小,否则将导致运行错误.缓冲区的地址以CV_STRUCT_ALIGN[当前为sizeof(double)]的整数倍来调整.
功能
函数cvMemStorageAllocString在存储块中分配一文本字符串
格式:
CvString cvMemStorageAllocString(CvMemStorage* storage,const char* ptr,int len = -1);
参数:
stoage 存储块.
ptr 字符串
len 字符串长度(不包括结束符'\0').如果次参数为负数,则函数计算该字符串的长度
说明:
函数cvMemStorageAlloString在存储块中创建一字符串的备份,并返回如下结构
typedef struct CvString
{
int len;
char* ptr;
}CvString;
该结构包含字符串长度(该长度可以通过用户传递,也可以通过计算得到)和指向被复制了的字符串指针.
功能:
函数cvSaveMemStoragePos保存内存块的地址
格式:
void cvSaveMemStoragePos(const CvMemStorage* storage,CvMemStoragePos* pos);
参数:
storage 内存块.
pos 内存块的顶部位置
说明:
函数cvSaveMemStoragePos将内存块的当前地址保存到参数pos中.函数cvRestoreMemStoragePos可获取该地址.
功能:
函数cvRestoreMemStoragePos恢复内存块的地址
格式:
void cvRestoreMemStoragePos(const CvMemStorage* storage,CvMemStoragePos* pos);
参数:
storage 内存块.
pos 新的内存块地址
说明:
函数cvRestoreMemStoragePos通过参数pos恢复内存块的地址.此函数与函数cvClearMemStorage是释放被占用内存块的唯一方法.
注意:没有方法可以用来释放内存块中被占用的部分内存.