1. ホーム
  2. c

[解決済み] mallocの結果はキャストするのですか?

2022-03-13 02:32:56

質問

この質問 で、ある人が提案した。 コメント ということを ではなく の結果をキャストします。 malloc .つまり、こうすればいいんだ。

int *sieve = malloc(sizeof(*sieve) * length);

よりも

int *sieve = (int *) malloc(sizeof(*sieve) * length);

なぜそうなるのでしょうか?

どうすれば解決するの?

TL;DR

int *sieve = (int *) malloc(sizeof(int) * length);

には2つの問題があります。キャストと、sizeofの引数に変数ではなく型を使っていることです。代わりに、次のようにします。

int *sieve = malloc(sizeof *sieve * length);

ロングバージョン

いいえ ;あなた しない は、その結果を鋳造します。

  • として、不要です。 void * は、この場合、自動的に安全に他の任意のポインタ型に昇格します。
  • コードが煩雑になる、キャストが読みにくい(特にポインタ型が長い場合)
  • 同じことを繰り返すことになり、一般に好ましくない。
  • を入れ忘れた場合、エラーを隠蔽することができます。 <stdlib.h> . これは、クラッシュの原因になります(もっと悪いことに。 ない が発生する可能性があります。) ポインタと整数のサイズが異なる場合、どうなるかを考えてみてください。この場合、キャストによって警告が隠され、返されたアドレスのビットが失われる可能性があります。注意: C99 では暗黙の関数がなくなり、宣言されていない関数が自動的に int .

補足すると、私が言ったのは「キャストしない」であって、「キャストしない」ではないことに注意してください。 必要 を鋳造してください。私の考えでは、たとえ正しくできたとしても、キャストを入れないと失敗です。キャストを入れるということは、そのリスクについて知らないということなのです。

また、コメント欄で指摘されているように、上記はC++ではなく、ストレートCについて述べていることに注意してください。私は、CとC++は別の言語であると固く信じています。

さらに付け加えると、あなたのコードは型情報を不必要に繰り返しています( int ) エラーの原因となることがあります。戻り値を格納するために使用されているポインタの参照を解除して、2つを一緒にロックする方がよいでしょう。

int *sieve = malloc(length * sizeof *sieve);

また、これは length を前面に出して視認性を向上させ、冗長な括弧を削除して sizeof を使用します。 は必要なだけです。 は、引数が型名である場合です。多くの人はこのことを知らない(あるいは無視している)ようで、そのためにコードが冗長になっています。覚えておいてください。 sizeof は関数ではありません! :)


移動中 length を前面へ かもしれない まれに視認性が向上する場合もあるが、一般的には次のように書いた方が良いので注意が必要である。

int *sieve = malloc(sizeof *sieve * length);

を残しているので sizeof を先にすることで、この場合、乗算は少なくとも size_t を計算します。

比べてみてください。 malloc(sizeof *sieve * length * width) vs. malloc(length * width * sizeof *sieve) をオーバーフローさせる可能性があります。 length * width としたとき widthlength よりも小さいタイプです。 size_t .