CvMemStorage
1、动态内存存储及操作函数
CvMemStorage
typedef struct CvMemStorage
{
struct CvMemBlock* bottom;
struct CvMemBlock* top;
struct CvMemStorage* parent;
int block_size;
int free_space;
} CvMemStorage;
内存存储器是一个可用来存储诸如序列,轮廓,图形,子划分等动态增长数据结构的底层结构。它是由一系列以同等大小的内存块构成,呈列表型---bottom 域指的是列首,top域指的是当前指向的块但未必是列尾.在bottom和top之间所有的块(包括bottom,不包括top)被完全占据了空间;在top和列尾之间所有的块(包括块尾,不包括top)则是空的;而top块本身则被占据了部分空间-- free_space指的是top块剩余的空字节数。新分配的内存缓冲区(或显示的通过cvMemStorageAlloc 函数分配,或隐示的通过 cvSeqPush,cvGraphAddEdge等高级函数分配)总是起始于当前块(即top块)的剩余那部分,如果剩余那部分能满足要求(够分配的大小)。分配后,free_space就减少了新分配的那部分内存大小,外加一些用来保存适当列型的附加大小。当top块的剩余空间无法满足被分配的块(缓冲区)大小时,top块的下一个存储块被置为当前块(新的top块)-- free_space被置为先前分配的整个块的大小。如果已经不存在空的存储块(即:top块已是列尾),则必须再分配一个新的块(或从parent那继承,见cvCreateChildMemStorage)并将该块加到列尾上去。于是,存储器(memorystorage)就如同栈(Stack)那样,bottom指向栈底,(top, free_space)对指向栈顶。栈顶可通过cvSaveMemStoragePos保存,通过cvRestoreMemStoragePos 恢复指向, 通过 cvClearStorage重置。
CvMemBlock
内存存储块结构
typedef struct CvMemBlock
{
struct CvMemBlock* prev;
struct CvMemBlock* next;
} CvMemBlock;
CvMemBlock 代表一个单独的内存存储块结构。 内存存储块中的实际数据存储在header块 之后(即:存在一个头指针 head指向的块 header ,该块不存储数据),于是,内存块的第i 个字节可以通过表达式 ((char*)(mem_block_ptr+1))[i]获得。然而,通常没必要直接去获得存储结构的域。
CvMemStoragePos
内存存储块地址
typedef struct CvMemStoragePos
{
CvMemBlock* top;
int free_space;
} CvMemStoragePos;
该结构(如以下所说)保存栈顶的地址,栈顶可以通过 cvSaveMemStoragePos保存,也可以通过 cvRestoreMemStoragePos 恢复。
________________________________________
cvCreateMemStorage
创建内存块
CvMemStorage* cvCreateMemStorage( int block_size=0 );
block_size:存储块的大小以字节表示。如果大小是 0 byte,则将该块设置成默认值 当前默认大小为64k.
函数 cvCreateMemStorage创建一内存块并返回指向块首的指针。起初,存储块是空的。头部(即:header)的所有域值都为0,除了 block_size 外.
cvReleaseMemStorage
释放内存块
void cvReleaseMemStorage( CvMemStorage** storage );
storage: 指向被释放了的存储块的指针
函数 cvReleaseMemStorage 释放所有的存储(内存)块 或者将它们返回给各自的 parent(如果需要的话)。 接下来再释放header块(即:释放头指针 head 指向的块 =free(head))并清除指向该块的指针(即:head = NULL)。在释放作为parent 的块之前,先清除各自的 child 块。
cvClearMemStorage
清空内存存储块
void cvClearMemStorage( CvMemStorage* storage );
storage:存储存储块
函数 cvClearMemStorage 将存储块的 top置到存储块的头部(注:清空存储块中的存储内容)。该函数并不释放内存(仅清空内存)。假使该内存块有一个父内存块(即:存在一内存块与其有父子关系),则函数就将所有的块返回给其parent.
cvMemStorageAlloc
在存储块中分配以内存缓冲区
void* cvMemStorageAlloc( CvMemStorage* storage, size_t size);
storage:内存块.
size:缓冲区的大小.
函数 cvMemStorageAlloc在存储块中分配一内存缓冲区。该缓冲区的大小不能超过内存块的大小,否则就会导致运行时错误。缓冲区的地址被调整为CV_STRUCT_ALIGN字节 (当前为 sizeof(double)).
cvMemStorageAllocString
在存储块中分配一文本字符串
typedef struct CvString
{
int len;
char* ptr;
}
CvString;
CvString cvMemStorageAllocString( CvMemStorage* storage,const char* ptr, int len=-1 );
storage:存储块
ptr:字符串
len:字符串的长度(不计算'�')。如果参数为负数,函数就计算该字符串的长度。
函数 cvMemStorageAlloString在存储块中创建了一字符串的拷贝。它返回一结构,该结构包含字符串的长度(该长度或通过用户传递,或通过计算得到)和指向被拷贝了的字符串的指针。
cvSaveMemStoragePos
保存内存块的位置(地址)
void cvSaveMemStoragePos( const CvMemStorage* storage,CvMemStoragePos* pos );
storage:内存块.
pos:内存块顶部位置。
函数 cvSaveMemStoragePos 将存储块的当前位置保存到参数pos 中。 函数 cvRestoreMemStoragePos可进一步获取该位置(地址)。
cvRestoreMemStoragePos
恢复内存存储块的位置
void cvRestoreMemStoragePos( CvMemStorage* storage,CvMemStoragePos* pos );
storage:内存块.
pos:新的存储块的位置
函数 cvRestoreMemStoragePos 通过参数 pos恢复内存块的位置。该函数和函数 cvClearMemStorage是释放被占用内存块的唯一方法。注意:没有什么方法可去释放存储块中被占用的部分内存。