スタック領域で動的な割り当てをするなら簡単な構造体・オブジェクトを使うと良いでしょう。
もちろん構造体の割り当ては 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