OpenCV基础知识——动态结构(二)

来源:互联网 发布:准备配置windows要多久 编辑:程序博客网 时间:2024/05/29 05:02

(7)cvMemStorageAlloc

该函数,首先判断Storage的剩余空间和待分配的空间的大小关系,若满足分配条件就直接在对应的TOP块中分配对应的空间,并且更改相关参数。如果待分配空间>剩余空间,则调用函数icvGoNextMemBlock()对storage进行调整,然后再进行分配。

源码:

  1. CV_IMPL void*
  2. cvMemStorageAlloc( CvMemStorage* storage, size_t size )
  3. {
  4.     char *ptr = 0;
  5.     
  6.     CV_FUNCNAME( "cvMemStorageAlloc" );
  7.     __BEGIN__;
  8.     if( !storage )
  9.         CV_ERROR( CV_StsNullPtr, "NULL storage pointer" );
  10.     if( size > INT_MAX )
  11.         CV_ERROR( CV_StsOutOfRange, "Too large memory block is requested" );
  12.     assert( storage->free_space % CV_STRUCT_ALIGN == 0 );
  13.     if( (size_t)storage->free_space < size )
  14.     {
  15.         size_t max_free_space = cvAlignLeft(storage->block_size - sizeof(CvMemBlock), CV_STRUCT_ALIGN);
  16.         if( max_free_space < size )
  17.             CV_ERROR( CV_StsOutOfRange, "requested size is negative or too big" );
  18.         CV_CALL( icvGoNextMemBlock( storage ));
  19.     }
  20.     ptr = ICV_FREE_PTR(storage);
  21.     assert( (size_t)ptr % CV_STRUCT_ALIGN == 0 );
  22.     storage->free_space = cvAlignLeft(storage->free_space - (int)size, CV_STRUCT_ALIGN );
  23.     __END__;
  24.     return ptr;
  25. }

 (8)icvGoNextMemBlock

该函数,如果Storage的storage->top->next!=0,则 将Storage的TOP块指针移动到下一个Block块上,然后设置好相关的参数,返回。   如果是新分配的Storage,其storage->top==0,若其也没有Parent节点,那么就给他分配一块storage->block_size大小的空间

然后将其作为该Storage的第一个Block,并设置相关的参数;若其有Parent节点,则在他的父节点上找到一块Block空间分配。并将该区域从其父节点上取下了。(注意最后一种情况是一个递归过程)

源码:

  1. static void
  2. icvGoNextMemBlock( CvMemStorage * storage )
  3. {
  4.     CV_FUNCNAME( "icvGoNextMemBlock" );
  5.     
  6.     __BEGIN__;
  7.     
  8.     if( !storage )
  9.         CV_ERROR( CV_StsNullPtr, "" );
  10.     if( !storage->top || !storage->top->next )
  11.     {
  12.         CvMemBlock *block;
  13.         if( !(storage->parent) )
  14.         {
  15.             CV_CALL( block = (CvMemBlock *)cvAlloc( storage->block_size ));
  16.         }
  17.         else
  18.         {
  19.             CvMemStorage *parent = storage->parent;
  20.             CvMemStoragePos parent_pos;
  21.             cvSaveMemStoragePos( parent, &parent_pos );
  22.             CV_CALL( icvGoNextMemBlock( parent ));
  23.             block = parent->top;
  24.             cvRestoreMemStoragePos( parent, &parent_pos );
  25.             if( block == parent->top )  /* the single allocated block */
  26.             {
  27.                 assert( parent->bottom == block );
  28.                 parent->top = parent->bottom = 0;
  29.                 parent->free_space = 0;
  30.             }
  31.             else
  32.             {
  33.                 /* cut the block from the parent's list of blocks */
  34.                 parent->top->next = block->next;
  35.                 if( block->next )
  36.                     block->next->prev = parent->top;
  37.             }
  38.         }
  39.         /* link block */
  40.         block->next = 0;
  41.         block->prev = storage->top;
  42.         if( storage->top )
  43.             storage->top->next = block;
  44.         else
  45.             storage->top = storage->bottom = block;
  46.     }
  47.     if( storage->top->next )
  48.         storage->top = storage->top->next;
  49.     storage->free_space = storage->block_size - sizeof(CvMemBlock);
  50.     assert( storage->free_space % CV_STRUCT_ALIGN == 0 );
  51.     __END__;
  52. }

(8)cvRestoreMemStoragePos( CvMemStorage * storage, CvMemStoragePos * pos )

该函数将Pos中相应的字段,赋值给Storage相对应的各个字段。注意当Storage是一个新初始化的情况时的特殊处理。

  1. CV_IMPL void
  2. cvRestoreMemStoragePos( CvMemStorage * storage, CvMemStoragePos * pos )
  3. {
  4.     CV_FUNCNAME( "cvRestoreMemStoragePos" );
  5.     __BEGIN__;
  6.     if( !storage || !pos )
  7.         CV_ERROR( CV_StsNullPtr, "" );
  8.     if( pos->free_space > storage->block_size )
  9.         CV_ERROR( CV_StsBadSize, "" );
  10.     /*
  11.     // this breaks icvGoNextMemBlock, so comment it off for now
  12.     if( storage->parent && (!pos->top || pos->top->next) )
  13.     {
  14.         CvMemBlock* save_bottom;
  15.         if( !pos->top )
  16.             save_bottom = 0;
  17.         else
  18.         {
  19.             save_bottom = storage->bottom;
  20.             storage->bottom = pos->top->next;
  21.             pos->top->next = 0;
  22.             storage->bottom->prev = 0;
  23.         }
  24.         icvDestroyMemStorage( storage );
  25.         storage->bottom = save_bottom;
  26.     }*/
  27.     storage->top = pos->top;
  28.     storage->free_space = pos->free_space;
  29.     if( !storage->top )
  30.     {
  31.         storage->top = storage->bottom;
  32.         storage->free_space = storage->top ? storage->block_size - sizeof(CvMemBlock) : 0;
  33.     }
  34.     __END__;
  35. }