Cを使うことについて

今度のプロジェクトはBREWなのでC言語を使う。今まで本格的に使ったことがなかったが、改めて触ってみるとなかなか面白い。


Cで一番癖があると思ったのは、型のメモリ領域の確保についてだ。Javaの場合、参照型はnew演算子を使用して明示的にメモリ領域を確保するが、Cの場合、宣言とメモリ領域の確保は同時に行われる。メモリ領域を確保したくなければ、ポインタとして宣言する必要がある。


だから、以下に示したJavaのコードをCで置き換えると、こんな感じになる。


class Foo {
int bar;
int zoo;

public static void main(String[] args) {
Foo foo_fill = new Foo();
Foo foo_empty = null;
}
}


typedef struct _Foo {
int bar;
int zoo;
} Foo;

int main() {
Foo foo_fill;
Foo *foo_empty;

return 0;
}

多分、C使いの人にとっては自明のことなんだろうが、ようやくポインタが多用される理由がわかった。インスタンスを生成しないで、型の宣言だけしたかった訳だ。


メモリ領域の確保について少し理解できるようになると、malloc()について別の利点がわかる。今まで「動的にメモリ領域が確保する関数」と考えていたが、今は「スコープに左右されないメモリ領域を確保する関数」と考えている。


例えば、以下のコードでは変数aは関数func()が終了した瞬間にメモリ領域が開放されるが、bはfree()で明示的にメモリ領域を開放しなければならない。


int func() {
char a[256];
char *b;

b = malloc(sizeof(char) * 256);
...
}

だから、malloc()を使えば、関数foo()で確保したメモリ領域を関数bar()で開放する、ということができる。


void foo(char **pstr) {
*pstr = malloc(sizeof(char) * 256);
}

void bar(char *str) {
free(str);
}

int main() {
char *str;

foo(&str);
...
bar(str);

return 0;
}

知らない言語を学ぶと、いつも新しい発見があるのがとても楽しい。