7

私は最近、この実験を試しました。この実験では、サイズが不明なメモリ要件に対して動的メモリ割り当てを行う代わりに、静的割り当てを行いました。私が配列a[i]を宣言したとき、私はi(配列のサイズ)変数を保持し、ユーザーの入力に依存していました。

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <conio.h>
 void function(int );
 int main(void)
 {
     int i;
     printf("Enter:");
     scanf("%d",&i);
     function(i);
     printf("i = %d\n",i);
     getch();
     return 0;
 }
 void function(int i)
 {
      char a[i];
      char b[4];
      strncpy(a,"hello",i);
      strcpy(b,"world");
      int j = 0;
      char *c = a;
      for( j = 0; j< 20; j++ )
           printf("%c",*c++);
 }

私の質問は次のとおりです。

  • そのような操作は合法ですか?
  • いいえの場合、コンパイラが警告やエラーを発行しないのはなぜですか?
  • このメモリはどこに割り当てられますか:スタックまたはヒープ?
  • なぜANSIC/ GCCがこれを許可するのですか?
4

6 に答える 6

16

そのような操作は合法ですか?

これを可変長配列と呼びます。

VLA は ANSI C99 で合法であり、一部の C99 以前のコンパイラの拡張機能として使用できます。GCC は、厳密な C99 としても、非 C99 コードの拡張としてもサポートしています。C++0x でも有効です。

いいえの場合、コンパイラが警告やエラーを発行しないのはなぜですか?

gcc の場合:

$ gcc -std=c89 src/vla.c  -Wall -ansi -pedantic
src/vla.c: In function ‘function’:, not dynamic array.
src/vla.c:17: warning: ISO C90 forbids variable length array ‘a’
src/vla.c:21: warning: ISO C90 forbids mixed declarations and code

MSDOS からの 'conio.h' の存在は、おそらく Microsoft Visual C++ コンパイラを使用していることを示しているので、心配する必要はありません。MS は、コンパイラを C++0x 標準にさらに準拠させるように取り組んでいますが、その C コンパイラ モードがどれほど標準的であるかについては何も主張していません。スペイン語の方言がフランス語の辞書にない理由を尋ねています。

このメモリはどこに割り当てられますか: スタックまたはヒープ?

これは自動オブジェクトであるため、ほとんどの C 実装は効率上の理由からスタックに入れます。

ANSI C/GCC がこれを許可する理由

これは、実行時に有効期間が関数呼び出しを超えない可変サイズの一時配列を作成するのに役立ちます。

于 2009-10-31T11:36:02.843 に答える
10

これは有効なC99です。

別のStackOverflowの質問で、より詳細な説明については、こちらをご覧ください。

于 2009-10-31T08:56:26.407 に答える
1

これは合法ですが、すべてのコンパイラがサポートしているわけではありません。少なくともVisualStudio<=2003afaikはそれをサポートしていません。

Ansi C ++ではないと思いますが、gcc-ansi-pedanticを試してください。

于 2009-10-31T08:55:05.083 に答える
0

ANSI C (C89) では、可変長配列は不正です。コンパイラの警告レベルを上げてみてください。警告/エラーが発生するはずです。

于 2009-10-31T09:43:20.870 に答える
0

コードは有効ですが、可変長配列を使用する際に注意すべき点が 1 つあります。

void function(int i)
{
     int a[i];
     .
     .
}

ここにはエラーチェックはありません。iが大きすぎると、このコードは失敗する可能性があります。

于 2009-10-31T18:43:52.960 に答える
0

スタック上の動的メモリ割り当て:

プログラム スタックにメモリを動的に割り当てるライブラリ呼び出し _malloca があります (ヒープに対する malloc と非常によく似ています)。

参考:_malloca

于 2010-07-13T06:50:11.527 に答える