CXCORE リファレンス マニュアル
- 基本構造体(Basic Structures)
- 配列操作(Operations on Arrays)
- 動的構造体(Dynamic Structures)
- メモリストレージ(Memory Storages)
- シーケンス(Sequences)
- セット(Sets)
- グラフ(Graphs)
- 木(Trees)
- 描画関数(Drawing Functions)
- データ永続性と実行時型情報(Data Persistence and RTTI)
- その他の関数(Miscellaneous Functions)
- エラーハンドリングとシステム関数(Error Handling and System Functions)
動的構造体(Dynamic Structures)
メモリストレージ(Memory Storages)
CvMemStorage
動的に拡張可能なメモリストレージ
typedef struct CvMemStorage
{
struct CvMemBlock* bottom;/* 最初に確保されたブロック */
struct CvMemBlock* top; /* 現在のメモリブロック − スタックの先頭 */
struct CvMemStorage* parent; /* 新たなブロックを確保する場所 */
int block_size; /* ブロックの大きさ */
int free_space; /* topブロック内の自由領域(バイト単位) */
} CvMemStorage;
メモリストレージは低レベルの構造体で,動的に拡張可能なデータ構造を持ち,シーケンスや輪郭,グラフ,細分化などに使われる. これは同じサイズのメモリブロックのリストとして編成されている. bottomフィールドはブロックのリストの先頭,topは現在使われているブロックを意味するが, リストの最後のブロックとは限らない.後者(ここではtop)以外のbottomからtopまでのブロックは全て占有されている. topを除くtopから最後までのすべてのブロックは空き領域で,topブロック自体は部分的に占有されている. free_spaceは,topの後ろに残されているバイト単位で示された自由領域を意味する.
もしくはcvSeqPushや cvGraphAddEdge などの高レベル関数によって間接的に確保された新たなメモリ領域は,そこに収まる場合には常に現在のブロックの最後に確保される. 確保後free_spaceは,適切なアライメントを保持するために,確保したバッファサイズにパディングを加えた分ずつ減らされる. 確保されたバッファがtopの利用可能な領域に納まらない場合, リストの次のストレージブロックがtopとして用いられ, free_spaceはメモリ確保前にブロックサイズにリセットされる.もし空きブロックがない場合,新しいブロックが確保され (または親から借りて,cvCreateChildMemStorageを参照), リストの最後に追加される.このようにこのストレージはスタックとして振る舞い, bottomがスタックの底, topとfree_spaceのペアがスタックの先頭を示す. スタックの先頭はcvSaveMemStoragePosで保存, cvRestoreMemStoragePosで復元, cvClearMemStorageでリセットされる.
CvMemBlock
メモリストレージブロック
typedef struct CvMemBlock { struct CvMemBlock* prev; struct CvMemBlock* next; } CvMemBlock;
typedef struct CvMemBlock
{
struct CvMemBlock* prev;
struct CvMemBlock* next;
} CvMemBlock;
構造体CvMemBlockは,メモリストレージの1ブロックを表現する. 実際のメモリブロックのデータはヘッダの後にあり, メモリブロックのi番目のバイトは((char*)(mem_block_ptr+1))[i]で取り出すことができる. しかし通常,ストレージ構造体のフィールドに直接アクセスする必要はない.
CvMemStoragePos
メモリストレージの位置
typedef struct CvMemStoragePos { CvMemBlock* top; int free_space; } CvMemStoragePos;
この構造体はスタックの先頭位置を保持しており, cvSaveMemStoragePosで保存, cvRestoreMemStoragePosで復元できる.
CreateMemStorage
メモリストレージを生成する
CvMemStorage* cvCreateMemStorage( int block_size=0 );
- block_size
- ストレージブロックのバイト単位のサイズ.0の場合,デフォルト値(現在は≈64K)が使われる.
関数cvCreateMemStorageはメモリストレージを生成し,そのポインタを返す.初期状態ではストレージは空である. block_sizeを除くヘッダのフィールドは全て0に設定されている.
CreateChildMemStorage
子メモリストレージを生成する
CvMemStorage* cvCreateChildMemStorage( CvMemStorage* parent );
- parent
- 親メモリストレージ.
関数 cvCreateChildMemStorageは,メモリ確保/解放機構の違いを除いて, 単純なメモリストレージに似た子メモリストレージを生成する. 子ストレージが新しいブロックをブロックリストに追加する必要がある場合, 子は親からブロックを取り出すことを試みる. 親に占有されていない利用可能な最初のブロックが取り出され,その部分は親のブロックリストから排除される. 利用可能なブロックがない場合,ブロックを確保するか,もし親の親が存在すれば,親はそこから借りる. つまり,それぞれのストレージが別のストレージの親や子になるような,チェインやさらに複雑な構造のメモリストレージが可能になる. 子ストレージが解放されるかクリアされた場合,その全てのブロックは親に返される.別の見方をすると,子ストレージは単純なストレージと同じである.
子ストレージは以下の状況において有用である.幾つかのストレージに分かれて存在する動的データを処理して, その結果を同じストレージに置く必要があるような状況を想像してほしい. 最も単純に,一時的なデータを入出力データと同じストレージに置く方法では,処理後のストレージは以下のようになる.
子ストレージを利用せずに動的なデータ処理を行った場合
このようにストレージの中央にごみが残ってしまう. しかし処理の始めに子メモリストレージを生成して,一時的なデータをそこに書き込み,最後に解放した場合,ごみは入力/出力ストレージに残らない.
子ストレージを利用して動的なデータ処理を行った場合
ReleaseMemStorage
メモリストレージを解放する
void cvReleaseMemStorage( CvMemStorage** storage );
- storage
- 解放するストレージのポインタ.
関数cvReleaseMemStorageは,ストレージの全メモリブロックを解放し,もし親がいれば親に返す. その際にストレージヘッダも解放され,ストレージへのポインタもクリアされる. 全ての子ストレージは親を解放する前に解放しておく必要がある.
ClearMemStorage
メモリストレージをクリアする
void cvClearMemStorage( CvMemStorage* storage );
- storage
- メモリストレージ.
関数cvClearMemStorageは,ストレージの先頭(空き領域の境界)を,一番最初に戻す. この関数はメモリを解放しない.もしストレージが親を持つ場合,この関数は親に全てのブロックを返す.
MemStorageAlloc
ストレージ内にメモリバッファを確保する
void* cvMemStorageAlloc( CvMemStorage* storage, size_t size );
- storage
- メモリストレージ.
- size
- バッファサイズ.
関数cvMemStorageAllocは,ストレージ内にメモリバッファを確保する. バッファサイズは,ストレージのブロックサイズを超えてはいけない. 超えた場合にはランタイムエラーが発生する. バッファアドレスは,CV_STRUCT_ALIGN(現時点では=sizeof(double))バイトにアライメントされる.
MemStorageAllocString
ストレージ内にテキスト文字列を確保する
typedef struct CvString
{
int len;
char* ptr;
}
CvString;
CvString cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, int len=-1 );
- storage
- メモリストレージ.
- ptr
- 文字列.
- len
- 文字列の長さ(終端の'¥0'は数えない).負の場合,この関数が長さを計算する.
関数cvMemStorageAllocStringは,メモリストレージ内に文字列のコピーを生成する. この関数はユーザが渡した,もしくは計算された文字列の長さとコピーされた文字列へのポインタを持つ構造体を返す.
SaveMemStoragePos
メモリストレージの位置を保存する
void cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos );
- storage
- メモリストレージ.
- pos
- 出力するストレージ先頭の位置.
関数cvSaveMemStoragePosは,ストレージの先頭の現在位置をパラメータposに保存する. 関数cvRestoreMemStoragePosで,この位置を復元することができる.
RestoreMemStoragePos
メモリストレージの位置を復元する
void cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos );
- storage
- メモリストレージ.
- pos
- 新しいストレージの先頭位置.
関数 cvRestoreMemStoragePosは,パラメータposからストレージの先頭を復元する. この関数と関数cvClearMemStorageは,メモリブロック内で占有されたメモリを解放する唯一の方法である. ストレージの占有部分の途中のメモリを解放する方法は無いことに十分注意すること.