Slide 1

Slide 1 text

C言語を知らない人がびっくりしそうな C言語の特徴 ~文字列編~ Apr. 23rd, 2023 Satoru Takeuchi twitter: satoru_takeuchi

Slide 2

Slide 2 text

はじめに ● 想定聴衆 ○ 「C言語は聞いたことはあるがどんなものか知らない」という人 ● はなすこと ○ C言語の特徴を紹介 ○ 今回のテーマは文字列 ● 環境 ○ OS: Ubuntu 20.04/x86_64 ○ gcc: Ubuntu 9.4.0-1ubuntu1~20.04.1

Slide 3

Slide 3 text

C言語における文字列とは? ● “string”といった文字列専用の型は存在しない ● 便宜的にNULL文字(‘\0’)で終わるcharの配列を文字列として使っている ○ これをNULL終端文字列やASCIIZなどと呼ぶ ○ 標準ライブラリの文字列操作関数も NULL終端文字列を扱う ● めんどくさい

Slide 4

Slide 4 text

初期化 char s[] = “foo”; メモリ ‘f’ ‘o’ ‘o’ ‘\0’ s

Slide 5

Slide 5 text

比較 char s1[] = “foo”; char s2[] = “bar”; // strcmp()は第一引数と第二引数が同じ文字列なら 0、そうでないなら非0を返す // 同じでない場合の定義はもうちょっと複雑。気になれば man strcmpを参照 strcmp(s1, s1); strcmp(s1, s2); strcmp(s2, s1); メモリ ‘f’ ‘o’ ‘o’ ‘\0’ s1 ‘b’ ‘r’ ‘a’ ‘\0’ s2 …

Slide 6

Slide 6 text

長さの確認 char s[] = “foo”; int n = strlen(s); // foo(s, n); ‘f’ ‘o’ ‘o’ ‘\0’ s NULL文字が見つかるまで走査

Slide 7

Slide 7 text

コピー char s1[] = “foo”; char s2[5]; strcpy(s2, s1); char s3[]; s3 = strdup(s1); // 標準ライブラリ関数ではない&後でメモリ解放が必要 メモリ ‘f’ ‘o’ ‘o’ ‘\0’ s1 ‘f’ ‘o’ ‘o’ ‘\0’ s2 … コピー

Slide 8

Slide 8 text

コピーの落とし穴: ポインタのコピーをしてしまう char s1[] = “foo”; char s2[]; s2 = s1; ‘f’ ‘o’ ‘o’ ‘\0’ s1 s2

Slide 9

Slide 9 text

コピーの落とし穴: バッファ長が足りない char s1[] = “foo”; char s2[2]; strcpy(s2, s1); // strncpy(s2, s1, sizeof(s2)); // s2[sizeof(s2)-1] = ‘\0’ メモリ ‘f’ ‘o’ ‘o’ ‘\0’ s1 ‘f’ ‘o’ ‘o’ ‘\0’ s2 … コピー 破壊!

Slide 10

Slide 10 text

連結 char s1[] = “foo”; char s2[] = “bar”; // char s3[] = a + b はできない char s3[10]; strcpy(s3, s1); strcat(s3, s2); ‘f’ ‘o’ ‘o’ ‘\0’ … ‘b’ ‘a’ ‘r’ ‘\0’ ‘f’ ‘o’ ‘o’ ‘\0’ s1 s2 s3 strcpy(s3, s1) ‘f’ ‘o’ ‘o’ ‘\0’ … ‘b’ ‘a’ ‘r’ ‘\0’ ‘f’ ‘o’ ‘o’ ‘b’ ‘a’ ‘r’ ‘\0’ s1 s2 s3 strcat()

Slide 11

Slide 11 text

まとめ ● C言語では文字列を扱う専用の型は存在しない ● 一般にNULL終端文字列を使う ● とても扱いが面倒くさい ○ バグやセキュリティホールの温床になりがち