LoginSignup
35
24

More than 5 years have passed since last update.

C言語で動的なサイズのメモリ確保が必要となれば、典型的にはmallocfreeの出番ですが、allocaというものもあります。

C言語での変数の寿命

オブジェクト指向な言語の多くでは、ガベージコレクタが入っているので、「オブジェクトの寿命」≒「オブジェクトへの参照が存在する間」ということになります。これに対して、C言語(やC++)では、ガベージコレクタのような高度な仕組みはないので、変数の寿命は次の2つのどちらかになります。そして、C11で加わった可変長配列を別として、配列を確保するときもサイズは固定のしか取れません。

  • 自動変数…スコープに入ったところで変数が用意され、スコープを抜けたところで解放される
  • 静的変数・外部変数…プログラムの開始から終了まで存在し続ける

これらに当てはまらない操作をしようと思えば、ライブラリ関数を使ってポインタ経由で使うほかありません。

allocaとは

ふつう、C言語で動的確保をしようと思えばmallocfreeの流れですが、標準関数ではないものの多くの環境にalloca、あるいは_allocaという関数があります。この関数の特徴としては、「メモリ領域をスタックに取る」ということがあります。そのため、

  • 使い終わった後のfreeの必要がない(というより、してはならない)
  • スコープを抜ければ自動で解放される
    • 返り値としてこのメモリ領域へのポインタを返してはいけない
  • オーバーヘッドが少ない
  • アセンブラで埋め込み展開されるような環境もある(alloca関数へのポインタを取れない)
  • 巨大な領域を取るとスタックオーバーフローで死ぬ

というような特徴があります。

この前使った場面では、実行時までサイズが決まらない配列を確保する必要があったのですが、その配列自体は外からアクセスする必要がなく、そして処理全体に対するmallocのオーバーヘッドがかなりのものになる、という状況だったので、「必要な長さが小さな時にはallocaに切り替える」ようにしたところ、3割程度高速化した、ということがありました。

35
24
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
24