プログラムローダーと呼ばれる仕組みがある。
ただ、WindowsではPCの電源を入れて起動するタイミングでプログラムローダーが語られる。
マイコン(OSがない)ならある決まったROMから実行し、RAMに変数領域やヒープ領域、スタック領域を設定する。
Windowsを使っているならa.exeを実行しらたらcmd.exeかマウスクリックで実行した場合はExploreはOSがプロセスを作るために提供しているAPIを使ってプロセスを作り、a.exeファイルをほぼそのまま4GBのメモリ空間に展開する。ほぼそのままというのはコンパイラがWindows用のメモリ空間を知っているのでコンパイラはその空間にマッチするようにコンパイルしているためです。
そのメモリ空間とは、具体的にはセクションというものがある。
.text プログラムコード
.data 実行から終了までいつでも使える初期値を持つデータ
.bss 実行から終了までいつでも使える初期値を持たないデータ
.rodata 定数。プログラムコードと同様書き込みできない領域
コードは実行時に変化することはない(最近のスクリプト言語はそうでもない)
定数なども変化しない。データはdataとbssがあるがこれらはコード上で宣言していないと作られない。
では、実行時でないとデータのサイズが決まらない場合どうすればいいのか?
1、グローバル変数のサイズ多めに宣言しておく
2、実行時にmalloc関数を使う
1の方法は、無駄がおおい。普通は2だ。
実行時にメモリをどの領域から確保するのか?
1、スタック領域
2、ヒープ領域
a.exeがメモリの下の方にロードされ、メモリの上限にスタックが設定される。
スタックが増える時にはアドレス値を減らすような仕組みになっている。
a.exeからスタックの間におおきな空き領域がある。これをヒープ領域と呼ぶ。
malloc関数は、このヒープ領域にメモリ領域を配置する。
さて、
int *p=malloc(15);
mallocは15バイト分のヒープ領域のメモリを確保し、その先頭アドレスをpに入れる。
mallocは、ヒープ領域で動的に確保したメモリのマップを持っている。動的なメモリ領域が不要になったらマップ上からも削除する必要がある。
free(p);
で開放する。開放されてメモリ領域は再利用が可能な状態になる。
OpenCVでもmallocやfreeに似た関数がいっぱいあります。
気を付けて欲しいのは、
char a;
char *p;
p=&a;
ならchar a;で自分がメモリ領域を確保しているので意識できるが。
int *p=malloc(15);
malloc自体がこっそりとメモリ領域を確保している点です。
このことを忘れるとよくやるのがfree忘れです。
アプリケーションの終了時に妙なメモリエラーを見ることがあったら疑おう。
「今日の訪問数: - 」
「昨日の訪問数: - 」
「今までの訪問数: - 」
最終更新:2009年12月11日 22:33