バグ:文字列のコピー

Posted: 2012年10月23日

文字列のコピーする際によく書いてしまうバグを紹介します。

プログラムプログラム:

 #include  <stdio.h>
 int main(int argc, char *argv[])
 {
    CString strSrc = _T("12345あいうえおかきくけこ");
    int nDestSize = strSrc.GetLength() + 1;
    TCHAR *pszDest = new TCHAR[nDestSize];

    // 文字列のコピー
    _tcscpy_s(pszDest, nDestSize, strSrc );

    return 0;
 }

このプログラムにどのような文字列コピー関連のバグがあると思いますか?

  • ユニコードの場合は、配列のサイズが小さすぎる

改善版プログラム改善版プログラム:

 #include  <stdio.h>

 int main(int argc, char *argv[])
 {
    CString strSrc = _T("12345あいうえおかきくけこ");
    int nDestSize = (strSrc.GetLength() + 1) * sizeof(TCHAR);
    TCHAR *pszDest = new TCHAR[nDestSize];

    // 文字列のコピー
    _tcscpy_s(pszDest, nDestSize, strSrc );

    return 0;
 }

解説解説:

マルチバイトコードとユニコードでは、GetLengthの結果が異なるため
TCHARのサイズをかける必要があります。

GetLengthの挙動

マルチバイトコード ユニコード
バイト数 文字列長
半角 1 全角 2 ※1 すべて 1

※1 一部例外あり

マルチバイトコードは、
 1バイトと2バイトが混在した文字コードを指します。
 (UTF-8も仲間)

ユニコードは、
 すべての文字列を2バイトの文字コードを指します。
 主にUTF-16等

カテゴリー: バグ, プログラム | タグ: , , , | 1 コメント »

1 コメント on “バグ:文字列のコピー”

  1. 1. 投稿者: Aki  日付 : 2016年02月05日 09時43分:

    改善版プログラムについて。
    確保している配列のサイズが無駄に必要なサイズの2倍になっています。
    型がTCHARなのでnewするサイズは「strSrc.GetLength() + 1」のままで構いません。
    _tcscpy_sをコールする際にsizeof(TCHAR)を掛ければよいかと。

    あと、どちらもdelete[]コールしていないですね。


コメント