53.1. alloca() の使用法

 スタック領域で動的な割り当てをするなら簡単な構造体・オブジェクトを使うと良いでしょう。

 もちろん構造体の割り当ては alloca() を使わなくてもできます。

 例えばポインターが配列を指していない以下のような場合ですね。

main.c. 

  1 #include <alloca.h>
  2 #include <stdio.h>
  3
  4 typedef struct _foo {
  5   int x,y,z;
  6 } foo;
  7
  8 int main()
  9 {
 10   void* ptr = NULL;
 11   foo f;
 12   ptr = (void*)&f;
 13   printf("%p\n",ptr);
 14   return 0;
 15 }

ビルドと実行結果. 

$ gcc main.c
$ ./a.out
0x7ffdc9be8ddc

 この例だと alloca() をわざわざ使うのは手間に感じられます。

 まあそれでも alloca() の方が見た目は良いですけどね…

 (´・ω・`)

 ポインターが配列を指す以下のソースコードでは alloca() によって割り当てを済ませると、コードが意図していることが良くわかります。

main.c. 

  1 #include <stdio.h>
  2 #include <alloca.h>
  3
  4 typedef struct _foo {
  5   int x,y,z;
  6 } foo;
  7
  8 int main()
  9 {
 10   foo* foo_ptr = NULL;
 11   foo* tmp;
 12   int i;
 13
 14   foo_ptr = alloca(sizeof(foo)*4);
 15   tmp = foo_ptr;
 16   for(i = 0; i < 4; i++){
 17     foo_ptr->x = i+1;
 18     foo_ptr->y = i+2;
 19     foo_ptr->z = i+3;
 20     foo_ptr++;
 21   }
 22
 23   printf("foo_ptr[0].z => %d\n",tmp->z);
 24   printf("foo_ptr[3].x => %d\n",(tmp+3)->x);
 25   printf("foo_ptr[1].y => %d\n",(tmp+1)->y);
 26
 27   return 0;
 28 }

ビルドと実行結果. 

$ gcc main.c
$ ./a.out
foo_ptr[0].z => 3
foo_ptr[3].x => 4
foo_ptr[1].y => 3

 この場合の配列は 4 個分の要素を持てますが、これは alloca() によって動的に決定できます。

 あとは一応コードの捕捉をしておきますか… (´・ω・`)

 foo_ptr は 4 個分の foo 構造体を動的に割り当てたポインターです。

 そして tmp は最初のアドレスを記憶しておくポインター変数となります。

 for ループの箇所では 4 回の反復をし、そのたびにポインターをインクリメントして、次の foo を指すアドレスに foo_ptr のポインターを更新しています。

 printf() 文については foo_ptr を最初の位置に巻き戻すのが面倒くさいので tmp から各 foo オブジェクトにアクセスしています。

Copyright 2018-2019, by Masaki Komatsu