メモリー
C言語で通なければならない関門のメモリ。使ってるメモリが状態がどうなってて、何をどう使ってるのを把握しておかないとnull pointerでスタックトレースなんて生温い結果じゃなくて、segmentation fault。はい終了。原因なんて教えてくれれやしない。プログラム終了。「落ちた」なんて連呼されることになります。
メモリは静的メモリと動的メモリの2種類があります。静的メモリとは変数を宣言したら勝手に確保してくれるお手軽メモリ。「 char a[10] 」でsize(char*10)分のメモリが自動で確保されます。しかし、動的メモリは自分で確保してから変数に割り当ててあげなければなりません。なんだか面倒ですね。
しかし静的メモリは上限(スタック領域)があるし、なによりスコープ(見える範囲や確保されている範囲)があるので、全体的に使いたいときなど逆に使い辛いです。グローバル変数なんてスコープもありますが、スパゲッティの名人になれそうなワードです。
■静的メモリ
--- main.c --- #include <stdio.h> void func() ; void sub() ; int ggg; //グローバル変数 int main() { int lll; //ローカル変数 ggg = 1; lll = 2; printf("main ggg:%d lll:%d\n",ggg,lll); func(); printf("main ggg:%d lll:%d\n",ggg,lll); sub(); printf("main ggg:%d lll:%d\n",ggg,lll); } void func() { int lll;// ローカル変数 main.cのlllとは別物 lll = 4; printf("func ggg:%d lll:%d\n",ggg,lll); ggg = 5; lll = 6; printf("func ggg:%d lll:%d\n",ggg,lll); // ここでlllは開放 } --- sub.c --- #include <stdio.h> extern ggg;//グローバルを見えるようする void sub() { int lll;// ローカル変数 main.cのlllとは別物 lll = 7; printf("sub ggg:%d lll:%d\n",ggg,lll); ggg = 8; lll = 9; printf("sub ggg:%d lll:%d\n",ggg,lll); // ここでlllは開放 }
■結果
$ gcc main.c sub.c $ ./a.out main ggg:1 lll:2 func ggg:1 lll:4 func ggg:5 lll:6 main ggg:5 lll:2 sub ggg:5 lll:7 sub ggg:8 lll:9 main ggg:8 lll:2
■動的メモリ
メモリを確保しないと
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char a[4]; char *b; strcpy(a,"123");//すでにaの領域は確保されているので使える strcpy(b,"123");//まだbの領域は無いので落ちる printf("[%s][%s]\n",a,b); }
■結果
$ gcc main.c $ ./a.out Segmentation fault
メモリを確保(malloc)する。使い終わったら開放(free)してね。
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char a[4]; char *b; strcpy(a,"123");//すでにaの領域は確保されているので使える b = (char*)malloc(4); strcpy(b,"123");//まだbの領域は無いので落ちる printf("[%s][%s]\n",a,b); free(b);//開放は忘れずに。メモリリークです。 }
■結果
$ gcc main.c $ ./a.out [123][123]