4

malloc 呼び出しに対する構造体のサイズについて言及する場合、構造体の名前と逆参照された構造体ポインター変数について言及する方がよいでしょうか?

例:

struct ExampleStruct
{
  int x;
  char arr[40];
};

int main()
{

  struct ExampleStruct *Y = NULL;

  Y = malloc(sizeof(struct ExampleStruct)); //Is this better?

  Y = malloc(sizeof(*Y)); //Is this better?  

}

個人的sizeof(struct ExampleStruct)には、多くの開発者が 2 番目のメソッドで '*' を忘れて間違いを犯しているのを見てきました。つまり、誤って入力したmalloc(sizeof(Y))場合、割り当てられるメモリはわずか 4 バイトになります。しかし、私はそれが一般的にも使用されているのを見てきました。

4

4 に答える 4

5

私は断然2番の方が好きです。everyの宣言された型がY変更された場合でも、その行は正しく機能します。

于 2012-05-16T05:11:25.173 に答える
4

K&R 2nd Edition を調べたところ、 の使用に関連する 3 つの例が見つかりましたmalloc()

  • 142ページ:return (struct tnode *) malloc(sizeof(struct tnode));

  • 145ページ:np = (struct nlist *) malloc(sizeof(*np));

  • 146ページ:return (Treeptr) malloc(sizeof(Treenode));

異なる形式についての特別な議論はありませんでした。序文に「プログラムのローカル テストに Bjarne Stroustrup の C++ トランスレータを広範囲に使用しました」という注記があります。これは 1989 年の C 標準が完成する直前に書かれたもので (私のコピーの表紙には「ドラフト案 ANSI C に基づく」と書かれているため、当時は標準コンパイラはありませんでした)、これはすべてのmalloc()呼び出しでの明示的なキャストを説明している可能性があります —これらは C++ で必要です。

したがって、「創設者」は両方の形式を使用しました。

sizeof(*variable)変数の型が変更されても、このコードを変更する必要がないように、最新のスタイルは表記法を使用することです(C ではキャストを省略します)。キャストを追加すると、その利点はなくなります。

sizeof(type)私の古いコードのほとんどは、K&R C のスタイルのエミュレーションの一部として、この表記法を使用する傾向があります。私の新しいコードのほとんどは現在、このsizeof(*variable)表記法を使用しています。C だけでなく C++ でもコードをコンパイルする予定がある場合は、キャストも入れます。

于 2012-05-16T05:43:36.483 に答える
1

私が好む:

Y = malloc(sizeof(struct ExampleStruct));

これはデータ型であるため、別の目的で乗算できます。元:

Y = malloc(sizeof(struct ExampleStruct) * 5);

元:

int *i;

私は好むだろう:

i = malloc(sizeof(int));

よりも、

i = malloc(sizeof(*i);

また、念のために言っておきますが、この変数iは へのポインターintであり、 へYのポインターstruct ExampleStructです。

于 2012-05-16T05:37:12.400 に答える
1

2 番目の典型的な議論は、Y の型が変更されても、 がmalloc()まだ機能するということです。ただし、通常、ステートメントの後に初期化コードがあり、Y の古い型を初期化します。新しい型でまだ機能している場合は、少なくともそれを確認する必要があります。タイプを「正常に機能する」ように変更するには、さらに多くの計画が必要です。

しかし、さらに、2 番目のコードは通常、記述するコードが少なく、後で読み取るコードも少なくなります。

私はさらに一歩進んで、そのような場合に Create および Destroy 関数を使用することを好みます。Create 関数は void ポインターを返しませんが、正しい型を返します。したがって、Y の型が変更されても、呼び出しを変更しない (および次の初期化コードを確認しない) 場合、コンパイラはエラーを返します。

malloc()さらに、これにより、コード全体にランダムなfree()呼び出しをスローするよりも、リソース管理がはるかに簡単になります。

于 2012-05-16T05:39:47.597 に答える