以下は、「C++ から始める - 制御構造からオブジェクトまで、6e」の 586 ページのコードの修正版です。
#include <iostream>
using namespace std;
int countChars(char *, char);
int main()
{
const int SIZE = 5;
char userString[SIZE];
char letter;
cout << "Enter a string: ";
cin.getline(userString, 10);
letter = '\0';
cout << "a appears ";
cout << countChars(userString, 'a') << " times.\n";
cin >> letter;
return 0;
}
int countChars(char *strPtr, char ch)
{
int times = 0;
while (*strPtr != '\0')
{
if (*strPtr == ch)
times++;
strPtr++;
}
return times;
}
プログラムを実行し、「aaaabba」と入力します。
ここで、特にメモリへの不正な書き込みを導入しようとしました。たとえば、char 配列のサイズが 5 であると宣言しますが、プロンプトが表示されたら 4 文字 (5 から \0 の長さを引いたもの) を超える文字を入力します。
システムが「userString」の直後に「letter」にメモリを割り当てたと仮定すると、「letter」に何かを書き込むと、「extended」userString の対応する場所が上書きされることになります。
したがって、メモリは [a][a][a][a][\0][b][a][\0] のようになります。
次に、countChars 関数を実行すると、本によると、最初の 4 つの a の直後にある「\0」文字で停止するはずです。
このロジックにより、文字列に 4 つの a があることが出力されるはずです。
実際には、プログラムは 5 つの a があると言っています。
私の推論のどこが間違っているのでしょうか?
編集 #1:これは本のコードではありません。それは変更されたコードです。
編集 #2:特に文字列オーバーフローを導入するためにコードを変更しました。意図的にこれを行ったのは、メモリが実際に自分の思うように機能するかどうかを確認したいからです。ですから、私が聞きたいのは、バグが期待どおりに機能しない理由についての確かな説明です。
編集 #3:コンパイラはスタックの破損について不平を言いますが、何が起こるかを見たいので、「続行」を押します。
ありがとうございました。