_s
VC++ 8.0でCRT のセキュリティ強化のために今まであったC関数が一部置き換えられている。(とはいえ昔のも使えるのだが。)調べたわけではないが、ほとんどの置き換えられた関数は、元の関数名に「_s」のポストフィックスがつけられている。単に関数名が変わっただけでなく引数がいじられているのも多いので注意して使わなければならない。
sscanf_s
sscanfは、文字列をフォーマットに従ってパースする関数であるが、CRTセキュリティ強化版ではsscanf_sを使う(似たものに_sscanf_s_l、swscanf_s、_swscanf_s_lなど)
ここで単にプログラム中のsscanfをsscanf_sに置き換えただけでは正常に動作しないことがあるので注意して欲しい。MSDNにも記述されているが、
型フィールド文字 c、C、s、S 、および [ を使用する場合は、バッファ サイズのパラメータ sizeOfBuffer が必要です。
ということである。これは、つまり文字のパースをする場合にその結果を受け取るバッファのサイズを引数に追加する必要があるということである。
今まで、
1 2 3 |
char src[] = "hoge"; cahr dst[ 16 ]; sscanf( src, "%s", dst ); |
このような感じで動いていたものは、
1 2 3 |
char src[] = "hoge"; char dst[ 16 ]; sscanf_s( src, "%s", dst, sizeof( dst ) ); |
というようにさらにバッファサイズの引数も追加しなくてはならない。もしこのようなサイズを記述しなかった場合、単に読み込めなかったということで帰り値0が帰るか、たとえば次のようなフォーマット指定の場合
1 2 3 4 |
char src[] = "hoge 1"; char dst1[ 16 ]; int dst2; sscanf_s( src, "%s %d", dst1, &dst2 ); |
しばらくだんまりしたあと、
xxxxxxxx.exe の 0x7c9778ae でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00030fe0 に書き込み中にアクセス違反が発生しました。
こんなエラーが出てしまう。これは、dst1のサイズが&dst2というポインタの値であるとされてしまうためだと考えられる。画面下の出力には、
xxxxxxxx.exe の 0xfdfdfdfd で初回の例外が発生しました: 0xC0000005: 場所 0xfdfdfdfd を読み込み中にアクセス違反が発生しました。
このような内容のデバッグ出力が大量に書かれる。