web-dev-qa-db-ja.com

malloc()の戻り値を明示的にキャストする必要がありますか?

私は次のケースについて尋ねたかった:

char *temp;
temp = malloc(10);

mallocの戻り値の型はvoid*なので、mallocによって返されるポインタはtempに割り当てられる前に暗黙的にchar*型にキャストされますか?これに関して規格は何と言っていますか?

ポインタ変数が次のような構造体タイプの場合:

struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));

メモリをstruct node*タイプにキャストせずにtempに割り当てる場合、暗黙的にstruct node*タイプにキャストされますか、それとも明示的にstruct node*タイプにキャストする必要がありますか?

52
mawia

Cのvoidポインターは、明示的なキャストなしで任意のポインターに割り当てることができます。

33
tekBlues

「自分自身を繰り返さない」という考え方が好きなら、malloc()呼び出しで、変数の宣言から型名を繰り返す必要がないことが魅力的です。人々が指摘したように、あなたはそうしないのです:ポインタは、関数ポインタを除いて、損失なしにvoid *との間で変換されます。

また、そのメモでは、sizeofを使用して繰り返す必要はありません。構造を割り当てるときの2番目の例は、次のように記述できます。

struct node *temp;
temp = malloc(sizeof *temp);

最高の方法は、それほど控えめな意見ではありません。

自分の繰り返しを避けることで、書くことの数が減り、その結果、それらの何かが間違っているというリスクが減ります。

sizeof引数のアスタリスクに注意してください。これは、「このポインタが指すオブジェクトのサイズ」を意味します。これは、もちろん「タイプstruct nodeのサイズ」と同じですが、繰り返さないでください。タイプ名。これは、sizeofが(コンパイル時に!)引数である式のサイズを計算するためです。この場合。 sizeof 3がタイプintの式のサイズを計算するのと同じように、sizeof *tempstruct nodeのインスタンスのサイズを計算します。

確かに、繰り返しますsomething、つまり変数名自体ですが、それは多くの場合、より単純な式であり、正しく理解するのが簡単であり、コンパイラーがエラーを見つけるのも簡単です。

51
unwind

Cはvoid*から暗黙的にキャストするため、キャストは自動的に行われます。 C++のみでの変換tovoid*は暗黙的に行われ、他の方向では明示的なキャストが必要です。

10
sth

C++では明示的にキャストする必要がありますが、これは実際には、それを行うことを伝える言語にすぎません。
Cでは、キャストする必要はまったくありません。メモリは単なるメモリです。最新のC標準で必要かどうかを調べるには、検索を行う必要があります。

3
Martin Beckett