The Delphi Bug List

Entry No.
676
VCL - 一般 - INIファイル - TIniFile
TIniFile.ReadString の Default 引数に空白文字で終わる文字列を渡すと、"invalid page fault in module KRNL386.EXE at 0002:00005c83" が発生する
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 4.03 5.0 5.01 6.0 6.01 6.02 Kylix 1.0
Absent Gotcha Gotcha Gotcha Gotcha Gotcha Gotcha Gotcha Gotcha Gotcha Gotcha Gotcha Gotcha Gotcha N/A
解説
Reported by Frank Wittl; checked by Jordan Russell
バグ #424 も参照してください。

このバグは、存在しない INI ファイルのエントリーを読もうとする以下のようなコードを記述することで確実に再現できます。
IniString := IniFile.ReadString('Test', 'TestString', ' ');
3番目の引数であるデフォルト文字列が ' '(空白文字) という点に注意してください。' ' を削除すると、この問題は発生ません。

その他の注意:
  1. このバグは Windows のバージョンに依存します:Windows 95 と 98 ではバグが発生しますが、NT 4.0 SP6 と WIN2K では問題ありません。
  2. このバグは、Delphi 5 (SP1) と Delphi 6 とで再現されました。
ユーザーからのコメント
Space Case
11 Jul 2001  03:08 PM GM
私が行ったテスト(Win98 + D3.02)の結果をもとにすると、このエントリーの見出しは "... 空白文字を含む ..." ではなく、"... 空白文字で終わる ..." とするべきです。
anonymous
28 Nov 2001  09:36 PM GMT
結局これは、Microsoft Windows のバグです。

<quote MSDN>
半角スペースで終わる文字列を既定の文字列として指定することは避けてください。この関数は、lpReturnedString パラメータが指すバッファへ文字列をコピーする際に、文字列の最後に NULL を追加しますが、このとき、文字列の最後にある任意の数の半角スペースは削除されます。

Windows 95:lpDefault は定数パラメータ(LPTSTR ではなく LPCTSTR)と宣言されていますが、システムは lpDefault パラメータが指す文字列に NULL を追加した上で、lpReturnedString パラメータが指すバッファへこの文字列をコピーすることにより、文字列の最後にある任意の数の半角スペースを削除します。
</quote>


  IniFile.ReadString('Test', 'TestString', ' ');

これが呼ばれたとき、デフォルト文字列の ' ' は、ライトプロテクトされた仮想メモリ上に存在します。Windows はそこに書き込もうとしているのです。

理論的には、書き込み可能なメモリに一時的な文字列を生成することで、Borland はこの問題を回避することが出来るでしょう。しかし、一般に異常と思われる Windows 95/98 の振る舞いを修正することは出来ません。
Latest update of this entry: 2002-03-18
本家 The Delphi Bug List のエントリーはこちら
The Delphi Bug List 日本語訳 へ