文字列を元に戻す小さな C++ 関数があります。
void reverse1(string& s, int start, int end) {
if (s.empty()) return;
char tmp;
while (start < end) {
tmp = s[end];
s[end] = s[start];
s[start] = tmp;
++start;
--end;
}
}
この機能は正常に動作します。しかし、以下のようにcで書き直すと、ステートメント11でセグメントフォルトに遭遇しました。
5 void reverse2(char *s, int start, int end) {
6 if (!s) return;
7 char tmp;
8
9 while (start < end) {
10 tmp = s[end];
11 *(s + end) = *(s + start);
12 *(s + start) = tmp;
13 ++start;
14 --end;
15 }
16 }
関数を呼び出すドライバー プログラム:
int main() {
/* Flavor1 works */
string a = "hello world2012!";
reverse1(a, 0, a.length() - 1);
/* Flavor2 does not - segmentation fault */
char *b = "hello world2012!";
reverse2(b, 0, strlen(b) - 1);
}
プログラムのコンパイルには gcc v 4.6.1 を使用しています。gdb を使用してコードをステップ実行すると、プログラムが実行時にセグメンテーション違反でクラッシュします。
文字列 s は const ではありません。誰かがここで何が起こっているのか提案できますか? この問題を解決するにはどうすればよいですか。ありがとう。
更新: 文字列リテラルで reverse2 関数が呼び出されます。問題は、文字列リテラルを変更しようとしていたことです。Jim と H2CO3 が指摘したように、これは未定義の動作です。
文字列リテラルで初期化された文字列オブジェクト (a) と文字列リテラル (b) の正確な違いは何ですか?