最近、連結リストについての私の家庭教師による講義中に、彼は次のように宣言しました。
struct asd *head=(struct asd *)malloc(sizeof(struct asd));
これと比較して上記の宣言の違いは何だろうと思っています:
struct asd *head=malloc(sizeof(struct asd));
私が作成するすべてのリンクされたリストに後者を使用しているためです。ちなみに言語はCです。
最近、連結リストについての私の家庭教師による講義中に、彼は次のように宣言しました。
struct asd *head=(struct asd *)malloc(sizeof(struct asd));
これと比較して上記の宣言の違いは何だろうと思っています:
struct asd *head=malloc(sizeof(struct asd));
私が作成するすべてのリンクされたリストに後者を使用しているためです。ちなみに言語はCです。
基本的に違いはありません。問題は、C で他のポインター型に設定できるmalloc
a を返すvoid *
ことです。C++ では、最初に行われたように明示的な型キャストが必要になります。C では、malloc からの戻り値を型キャストすることを嫌がります。
したがって、あなたの家庭教師は最初に C++ を学び、次に C を学んでいる可能性があります。
以下は、C を使用する場合の通常の推奨事項です。
struct asd *head = malloc(sizeof(*head));
特にコードをリファクタリングする場合にタイプミスを減らすため、sizeof(*head)
代わりにを使用することをお勧めします。sizeof(struct asd)
それ以外の点では、この 2 つは同等です。
のリターンをキャストすることはお勧めしませんmalloc
。これにはプラスの効果がないからです。場合によっては、 の結果をキャストするとmalloc
悪影響があります。これは、 を含めるのを忘れた場合に、C99 以前のメッセージのエラー メッセージが抑制される可能性があるためです<stdlib.h>
。
脚注:の結果をキャストする唯一のもっともらしい理由malloc
は、同時に C と C++ であるコードを記述できるようにするためです。しかし、C と C++ の両方でコードを書かないでください。
malloc は void* ポインターを返すため、講師は正しい構文を使用し、正しい型に明示的にキャストしていました。コンパイラが自動的に変換したため、あなたがしていたことはうまくいきました。GCCがこれについて警告していたので、MSVCを使用したと思います(と思います)。
本当に違いはありません。Malloc は、特定のサイズ (構造体 asd のバイト数) のメモリを割り当てます。これは両方の場合に発生します。違いは、最初の例ではポインタ (単なるメモリ アドレス) がキャストされ、2 番目の例ではキャストされないことです。
ポインターをキャストしても、実際には「何もしません」。これは、ユーザー (およびコンパイラー) がポインターを特定の方法で考えやすくするために設計された構文糖衣です。繰り返しますが、この例では違いはありません。
明示的であるため、講師が使用した最初のアプローチを個人的に好みます。malloc によって返されたメモリアドレスが を指していると明示的に言っていますstruct asd
。内部的には、ポインターはポインターであり、ポインターです。明示的であることは、C ではほとんど常に良いことです。
malloc()
void ポインターを返します。C では、void ポインターは明示的なキャストなしで任意のポインターに割り当てることができます。そのため、明示的な cast( #1
) 自体は必要ありません。
#2
実際、あいまいなユーザビリティ エラーを避けるために 、cast() を避けるようにアドバイスするプログラマもいます。
を含めるのを忘れた場合stdlib.h
。コンパイラは、malloc()
が を返す関数であると想定し、明示的なキャストにより、 が返すポインタint
を に変換します。一部のプラットフォームでは、an のサイズとポインターのサイズが同じでない場合があるため、このような望ましくない型変換によってデータが破損する可能性があります。void*
malloc()
int
int
個人的には、これほどの理由はないと思いますが、古いヨーダの状態に似た哲学です。