Upgrade to Pro — share decks privately, control downloads, hide ads and more …

その57 C言語を知らない人が見たらびっくりしそうなC言語の特徴 ~文字列編~

その57 C言語を知らない人が見たらびっくりしそうなC言語の特徴 ~文字列編~

以下動画のテキストです。
https://youtu.be/PblZT66BmBk

Satoru Takeuchi
PRO

April 26, 2023
Tweet

More Decks by Satoru Takeuchi

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  5. 比較
    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

    View Slide

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

    View Slide

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

    コピー

    View Slide

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

    View Slide

  9. コピーの落とし穴: バッファ長が足りない
    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

    コピー
    破壊!

    View Slide

  10. 連結
    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()

    View Slide

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

    View Slide