可変長配列をグローバル変数として宣言するにはどうすればよいですか?
長さがスキャンされる前に可変長配列が関数で宣言されると、コンパイルはされますが実行されません。セグメンテーション違反が発生します。同じ宣言ステートメントがスキャンステートメントの下にシフトされると、正常に実行されます。
可変長配列をすべての関数でグローバルに使用できるようにしたい場合は、どうすればよいでしょうか? ここでの問題は、配列の長さが特定の関数でしかスキャンできないことです。
可変長配列をグローバル変数として宣言するにはどうすればよいですか?
長さがスキャンされる前に可変長配列が関数で宣言されると、コンパイルはされますが実行されません。セグメンテーション違反が発生します。同じ宣言ステートメントがスキャンステートメントの下にシフトされると、正常に実行されます。
可変長配列をすべての関数でグローバルに使用できるようにしたい場合は、どうすればよいでしょうか? ここでの問題は、配列の長さが特定の関数でしかスキャンできないことです。
サイズに使用する式はコンパイル時に計算する必要があるため、可変長配列 (つまり、ランタイム値でサイズ変更された配列) をグローバル変数にすることはできません。スタック上でのみ存続できます。おそらく、取得しているのは静的配列であり、サイズはコード内のどこで定義しているかによって異なります (依存するものを再定義しているため)。
グローバル ポインターと realloc() を使用して、必要に応じてサイズを変更できないのはなぜですか?
そんなことはできません。標準の草案には次のように書かれています。
6.7.6.2 配列宣言子
2 識別子が可変的に変更された型を持つと宣言されている場合、それは通常の識別子 (6.2.3 で定義) であり、リンケージを持たず、ブロック スコープまたは関数プロトタイプ スコープのいずれかを持つ必要があります。識別子が静的またはスレッド ストレージ期間を持つオブジェクトとして宣言されている場合、可変長配列型を持たないものとします。
また、
10 例 4 可変的に変更された (VM) 型のすべての宣言は、ブロック スコープまたは関数プロトタイプ スコープのいずれかでなければなりません。_Thread_local、static、または extern ストレージ クラス指定子で宣言された配列オブジェクトは、可変長配列 (VLA) 型を持つことはできません。ただし、静的ストレージ クラス指定子で宣言されたオブジェクトは、VM 型 (つまり、VLA 型へのポインター) を持つことができます。最後に、VM 型で宣言されたすべての識別子は通常の識別子である必要があるため、構造体または共用体のメンバーにすることはできません。
可変長配列をCでグローバル変数として宣言する方法はありません。サイズを知る前に割り当てる必要があるため、コンパイラはそれに割り当てる必要があるメモリの量を知ることができません。ただし、できること (およびすべきこと) は、動的に割り当てることです。
char* my_dynamic_array = NULL;
void f(unsigned int size)
{
if(!my_dynamic_array) {
my_dynamic_array = malloc(size);
}
/* do something with the array */
}
int main(void)
{
f(1024); /* set size dynamically */
/* do something with the array */
free(my_dynamic_array); /* free the allocated memory */
return 0;
}