malloc
ユーザーが入力するサイズの配列を作成する方法(以外)はありますか?
5 に答える
それはすべてコンパイラに依存します。
では可変長の自動配列が許可され
ISO C99
ており、拡張機能としてGCCは C90 モードと C++ でそれらを受け入れます。これらの配列は、他の自動配列と同様に宣言されますが、長さが定数式ではありません。ストレージは宣言の時点で割り当てられ、ブレースレベルが終了すると割り当てが解除されます。例えば:
FILE *
concat_fopen (char *s1, char *s2, char *mode)
{
char str[strlen (s1) + strlen (s2) + 1];
strcpy (str, s1);
strcat (str, s2);
return fopen (str, mode);
}
詳細については、これを参照してください。
1 つの方法は、VLA を使用することです (C99 では、「可変長配列」と呼ばれるものが定義されています)。
次に例を示します。
#include <stdio.h>
int use_a_vla (int n)
{
int vla[n]; /* Array length is derived from function argument. */
vla[0] = 10;
vla[n-1] = 10;
return 0;
}
int main (void)
{
int i;
scanf ("%d", &i); /* User input. */
use_a_vla (i);
}
VLA や をお持ちでない場合alloca()
は、非常に厄介ですが、移植可能なスタックベースの手法を次に示します。
int foo(int size)
{
if (size <= 64*1024)
{
unsigned char arr[64*1024];
return bar(arr, size);
}
else if (size <= 1*1024*1024)
{
unsigned char arr[1*1024*1024];
return bar(arr, size);
}
else if (size <= 64*1024*1024)
{
unsigned char arr[64*1024*1024];
return bar(arr, size);
}
else
return -1; // Assume it's too big
}
int bar(unsigned char arr[], int size)
{
...your code goes here...
}
int maincode(int size)
{
// Invoke bar() indirectly, allocating an array
// on the stack of at least 'size' bytes
return foo(size);
}
この手法は特にお勧めしませんが、ヒープではなくスタックに異なるサイズのメモリ ブロックを割り当てることができます。
まあ、これは衒学的ですが、独自のヒープ管理コードを記述して、malloc()以外のメモリ割り当て関数を呼び出すことができます。この答えが煩わしいというよりも面白いことを願っています。
malloc
について知らないので、避けようとしていると思いますrealloc
。
基本的に、C++ ベクトルが行うことを大まかに行う必要があります。配列が特定のサイズに成長すると、realloc
そのサイズの 2 倍になります。
realloc
可能な場合はメモリブロックを拡張し、不可能な場合はmalloc
新しいブロックを作成して内容をコピーします。