1

その場で文字列を逆にしようとしています。

void reverseStr(char *str)
{
 int i;
 int length;
 int last_pos;
 length = strlen(str);
 last_pos = length-1;

 for(i = 0; i < length / 2; i++)
 {
   char tmp = str[i];
   str[i] = str[last_pos - i];
   str[last_pos - i] = tmp;
 }
}

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400893 in reverseStr (str=0x400974 "Haus") at main.c:102
102         str[i] = str[last_pos - i];
(gdb) print i
$1 = 0
(gdb) print last_pos
$2 = 3
(gdb) print str
$3 = 0x400974 "Haus"
(gdb) print str[3]
$4 = 115 's'

読んでくれてありがとう。よくわかりません。この命令がどのようにエラーを引き起こす可能性がありますか? よろしく:)

4

3 に答える 3

5

のコードreverseStrは問題ありません。問題は呼び出し元のコードにあります。ほぼ確実に、文字列リテラルまたはその他の読み取り専用メモリを関数に渡しています。

ほとんどの場合、呼び出しコードは次のとおりです。

char *str = "my string";//str points to a literal which cannot be modified
reverseStr(str);

ただし、書き込み可能なメモリを渡す必要があります。このような:

char str[] = "my string";
reverseStr(str);
于 2013-03-20T20:01:23.997 に答える
1

関数に文字列リテラルを渡しています。文字列リテラルはCでは変更できません。

char *p = "this string is non modifiable";
reverseStr(p); // undefined behavior

代わりに、文字列で初期化された配列を使用してください。

char p[] = "this string is modifiable";
reverseStr(p); // OK
于 2013-03-20T20:01:43.203 に答える
0

この関数をどのように呼び出すかによって異なります。

  • 文字列定数のアドレスを渡す場合 ({char *str = "String"} 型の定義は文字列定数として呼び出されます。文字列定数は実行可能ファイルの .rodata セクションに配置されます)、例外が発生します。 .
  • 配列のアドレス (char arr[] = "String") を渡す場合、関数は機能します。
于 2013-03-20T20:16:48.143 に答える