blog

C言語の落とし穴と欠陥に関する注意事項

ステップ 1: Split 0) とそれが変更する変数は「戻り値が NULL の関数ポインタ」を意味します。2番目のステップと組み合わせると、0は「戻り値がNULLの関数へのポインタ」となります。 ま...

Mar 13, 2020 · 2 min. read
シェア

P16

解析(*(void(*)())0) ();

ステップ1:0)とandを分割、後者はアドレスの内容に対して、この式ではアドレスの内容が関数のエントリポイントであることを意味し、前者は強制的な型変換。

ステップ3:変更した変数が「戻り値がNULLの関数ポインタ」であることを解析します。2番目のステップと組み合わせると、「戻り値がNULLの関数ポインタ」ということになります。

要約すると、この文はアドレスを実行する関数を表しています。 typedefを使えば、ステートメントを簡略化できます。

 typedef void(*A)();
 (*(A)0) ();

P38

つの文字列sとtがありますが、それらを1つの文字列rに連結しますか?

 char *r;
 r = malloc(strlen(s) + strlen(t) + 1);
 if (!r){
 exit(1);
 }
 strcpy(r, s);
 strcat(r, t
 //メモリ空間を使い切った後);
 free(r);

特筆すべきは、その手順の3つの詳細:

  • malloc関数を使用してメモリを要求した後、要求が成功したかどうかをチェックする必要があります。
  • 文字列は /0 で終わるので、メモリーを要求するときに余分な文字スペースを要求する必要があります。
  • 要求されたメモリ領域を使用した後は、メモリリークを防ぐために解放する必要があります。

P61

つの非負整数の加算がオーバーフローするかどうかを判定します。

 //エラー、オーバーフローが起こると、結果がどうなるかについてのすべての仮定はもはや有効ではない。
 if(a + b < 0)
 complain();
 // 
 if((unsigned int)a + (unsigned int)b < INT_MAX)
 complain();
 // 
 if(a < INT_MAX - b)
 complain();
Read next

2列コレクションフレームワークMapをこれほど雄弁に説明する方法は見たことがない。

HashMapはスレッドセーフで、並行環境でも使えます。 チェインテーブルが長すぎ、配列が短すぎるため、ハッシュの衝突が頻発し、ツリー化にはあまり役に立ちません。ツリー化は配列の長さをチェックするために行うべきで、<64は展開のためであり、ツリー化のためではありません 要素が実行されたときに...

Mar 12, 2020 · 7 min read