5
tmpString = (char*)malloc((strlen(name) + 1) * sizeof(char));
tmpString = (char )malloc((strlen(name) + 1) * sizeof(char));

これらの2行の違いは何ですか?

私の理解では、2行目は間違っていますが、何らかの理由でコンパイラは何も言いません。

4

4 に答える 4

5

最初の行は、malloc が返す (void) ポインターを char へのポインターにキャストします。コンパイラに伝えているのは、「位置 X のメモリは文字配列として表示する必要がある」ということだけです。

2 番目のキャストは、malloc によって返されたポインターを単一の文字に変換します。それは複数の理由で悪いです:

  • ポインターをまったく別のものに変えたので、ポインターを失います
  • 文字のサイズがポインターのサイズよりもはるかに小さいため、ポインターの数値の大部分も失われます (多くの場合、ポインターのサイズは 32 または 64 ビットですが、文字は 8 ビットしかありません)。ビット) そして「余分な」ビットは破棄されます。

警告レベルが十分に高くなったコンパイラは、2 番目の割り当てについて警告する必要があると思います。

于 2013-03-27T22:50:06.960 に答える
2

はい、2行目に未定義の動作があります。ケースは明示的であるため、コンパイラーは、ユーザーが何をしているのかを知っていると単純に想定します。基本的に、2 番目のキャストは、ポインター値の最初のバイトを文字コードとして解釈します。最後の文は単なる説明です-正確にそれが起こるとは言えません。

于 2013-03-27T22:47:08.490 に答える
2

2 行目は間違っています (a にキャストするcharとポインタが 1 バイトに切り捨てられ、データtmpStringに無効なアドレスが含まれます)、C のすべてのキャストはチェックされないため、エラーが発生することはありません。

于 2013-03-27T22:46:52.807 に答える
0

tmpStringhas typeと仮定すると、少なくとも最新の標準char *では、2 行目は制約違反になるはずです。

6.5.16.1 簡単な代入

制約

1 次のいずれかが成り立つ: 112) — 左のオペランドはアトミック、修飾、または非修飾の算術型を持ち、右のオペランドは算術型を持つ。

— 左のオペランドには、右の型と互換性のある構造体または共用体型のアトミック、修飾、または非修飾バージョンがあります。

左オペランドは、アトミック、修飾、または非修飾ポインター型を持ち、(左辺値変換後に左オペランドが持つ型を考慮して) 両方のオペランドは、互換性のある型の修飾または非修飾バージョンへのポインターであり、左が指す型は右が指すタイプのすべての修飾子。

左オペランドは、アトミック、修飾、または非修飾ポインター型を持ち、(左辺値変換後の左オペランドの型を考慮して) 一方のオペランドはオブジェクト型へのポインターであり、もう一方は修飾または非修飾バージョンのポインターです。 void であり、左が指す型には、右が指す型のすべての修飾子があります。

— 左オペランドはアトミック、修飾、または非修飾ポインターであり、右オペランドは null ポインター定数です。または

— 左側のオペランドの型がアトミック、修飾済み、または非修飾の _Bool で、右側がポインターです。

または、何か不足していますか?

于 2013-03-27T23:33:08.577 に答える