私はCで動的な1D配列を作成する方法を学んでいます。以下のコードは次のことを試みます。
malloc
を使用して、タイプdouble
の値を保持する長さ10
の動的配列を作成します。j/100
の場合、配列の各エントリをj = 0, 1,..., 9
に設定します。次に、印刷します。realloc
を使用して、配列の最後に追加の空のエントリを追加します。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);
質問
私はこれを正しくコーディングしていますか?
私が見つけたチュートリアルでは、(double*)
を前に置かずにmalloc
を使用しています。例えば。、
int * pointer;
pointer = malloc(2 * sizeof(int));
これは、Visual Studio 2010、Windows 7ではコンパイルされません。エラーメッセージは
void型の値は、
int
型のエンティティに割り当てることはできません。
私ではなく、なぜそれらのチュートリアルで機能するのですか?私の例では、使用しているコンパイラが(int*)
を自動的に埋めているためだと推測できますか?
あなたは近いです。
Cでは(少なくとも1989年の標準バージョン以降)、malloc
およびrealloc
の前のキャストは不要です。Cは、型なしでvoid *
型の値をint *
に変換できるためです。これはnot trueであるため、発生しているエラーに基づいて、このコードをCではなくC++としてコンパイルしているように聞こえます。VS2010のドキュメントを参照して、コードのコンパイル方法を確認してくださいCとして.
以下は、malloc
呼び出しを記述するための私の好みのスタイルです。
double *data = malloc(10 * sizeof *data);
式*data
の型はdouble
であるため、sizeof *data
はsizeof (double)
と同等です。これは、malloc
のタイプが変更された場合、data
呼び出しを調整する必要がないことも意味します。
realloc
呼び出しに関しては、結果を一時ポインター値に割り当てる方が安全です。 realloc
は、バッファーを拡張できない場合にNULLを返すため、記述する方が安全です。
double *tmp;
...
tmp = realloc(data, 11 * sizeof *data);
if (!tmp)
{
// could not resize data; handle as appropriate
}
else
{
data = tmp;
// process extended buffer
}
MicrosoftのCのサポートは、1989年版の言語で終了することに注意してください。それ以来、言語標準の2つの改訂版があり、いくつかの新しい機能が導入され、古い機能が廃止されました。そのため、一部のCコンパイラは、宣言とコードの混合、可変長配列などのC99機能をサポートしますが、VS2010はサポートしません。
1)これを正しくコーディングしていますか?
主に。ただし、realloc
が失敗した場合、data = (double*)realloc(data,11*sizeof(double));
は割り当てられたメモリへの参照を失います。一時ポインタを使用してrealloc
の戻り値を保持し、NULL
(およびmalloc
の戻り値も確認する必要があります)。
2)私が見つけたチュートリアルでは、(double *)を前に置かずにmallocを使用しています。
Cでは、malloc
はvoid*
を返しますが、これは暗黙的に他のポインター型に変換できるため、キャストは必要ありません(キャストによってエラーが隠される可能性があるため、広く推奨されません)。 Visual Studioは、キャストが必要なC++としてコードを明らかにコンパイルします。
Cでは、malloc()
の戻り値をキャストしないでください。
また、malloc()
引数で型をエンコードすることはお勧めできません。これはより良い方法です:
double* data = malloc(10 * sizeof *data);