2012-10-01 6 views
24

私は以下のコードはこれを実行しようとすると、Cでダイナミックな1次元配列を作成する方法を学んでいます:Cの動的配列 - malloc/reallocについての私の理解は正しいですか?

  1. mallocを使用して、ダブルスを保持している長さ10の動的配列を作成します。
  2. j = 0,1、...、9の場合、配列の各エントリをj/100に設定します。その後、 を印刷してください。
  3. reallocを使用して空のエントリを配列の最後に追加します。
  4. 新しいエントリをj/100に設定し、各エントリを再度印刷します。

テスト

double* data = (double*)malloc(10*sizeof(double)); 

for (j=0;j<10;j++) 
{ 
     data[j]= ((double)j)/100; 
     printf("%g, ",data[j]); 
} 

printf("\n"); 

data = (double*)realloc(data,11*sizeof(double)); 

for (j=0;j<11;j++) 
{ 
    if (j == 10){ data[j]= ((double)j)/100; } 
    printf("%g, ",data[j]); 
} 

free((void*) data); 

質問

1)私はこの権利をコーディングするだろうか?

2)チュートリアルmallocは、(double*)を付けずに使用しています。例えば。これは、Visual Studio 2010上で私のためにコンパイルされません

int *pointer; 

pointer = malloc(2*sizeof(int)); 

は、Windows 7のエラーは、「void型の値がint型のエンティティに割り当てることはできません」です。

なぜ私はこれらのチュートリアルではうまくいかないのですか?私が使用しているコンパイラが、私の例では自動的に(int*)を記入しているからです。

+0

"void型の値をint型のエンティティに割り当てることはできません"は、* C *コンパイラが生成するエラーではありません。問題は* C++コンパイラ*を使用していることです。あなたのソースファイルの名前が ' .c'であることを確認してください。 –

答えて

31

もうすぐです。Cにおいて

(少なくとも規格1989年版以降)Cキャストなしint *にタイプvoid *の値を変換することができるので、mallocrealloc前キャストは、不要です。これはではなく、 C++の場合は真ですから、このコードをC++ではなくCでコンパイルしているように思えます。コードをCとしてコンパイルする方法を決定するためにVS2010のドキュメントを確認してください。

表現 *dataのタイプは doubleあるので sizeof *datasizeof (double)に相当し、

double *data = malloc(10 * sizeof *data); 

は、次のmalloc呼び出しを書くための私の好みのスタイルです。これは、タイプがdataの場合は、mallocコールを調整する必要がないことを意味します。

reallocコールでは、結果を一時的なポインタ値に割り当てる方が安全です。それはバッファを拡張することができないならば、それは

double *tmp; 
... 
tmp = realloc(data, 11 * sizeof *data); 
if (!tmp) 
{ 
    // could not resize data; handle as appropriate 
} 
else 
{ 
    data = tmp; 
    // process extended buffer 
} 

は、Cのために、Microsoftのサポートは、言語の1989バージョンで終わることに注意して書く方が安全ですのでreallocは、NULLを返します。それ以来、いくつかの新しい機能と廃止された古い機能を導入した言語標準の2つのリビジョンがありました。したがって、一部のCコンパイラは、混合宣言やコード、可変長配列などのC99機能をサポートしていますが、VS2010はそうではありません。

+0

ありがとう、とても助かりました。 – Legendre

+0

更新:VS2015はC99 +部分C11とWinXPターゲットのオプションをサポートしています。したがってMicrosoftは2015年にISO Cのサポートを継続しました。 –

4

Cでは、戻り値をmalloc()にキャストしないでください。

また、型をmalloc()引数でエンコードすることは悪い考えです。これは良い方法です:

double* data = malloc(10 * sizeof *data); 
+1

これがコンパイルされます。しかし、Visual Studio 2010では、 "void型の値を使用してdouble型のエンティティを初期化することはできません"と警告しています。警告を無視するのは大丈夫ですか? – Legendre

10

1)私はこの権利をコーディングするのですか?

大部分です。しかし、reallocが失敗した場合はdata = (double*)realloc(data,11*sizeof(double));に割り当てられたメモリへの参照が失われます。reallocの戻り値を保持するために一時ポインタを使用し、NULLであることを確認してください(戻り値はmallocである必要があります)。

2)チュートリアル(double *)を前に置かずにmallocを使用していました。

はCで、mallocので何キャストが必要とされない(そしてエラーを隠すことができる鋳造ため広く落胆)、暗黙のうちに他のポインタ型に変換することができるvoid*を返します。 Visual Studioは、明らかに、キャストが必要なC++としてコードをコンパイルします。

+0

+1助けてくれてありがとうございます。 – Legendre

関連する問題