我有一个小的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单步执行代码时,程序会在运行时因分段错误而崩溃。
char字符串s不是const。有人可以建议这里发生了什么吗?我该如何解决这个问题。感谢。
更新: reverse2函数在字符串文字上调用。问题是我试图修改字符串文字。正如Jim和H2CO3指出的那样,这是一种未定义的行为。
现在用字符串文字和字符串文字(b)初始化的字符串对象(a)之间的确切区别是什么?
答案 0 :(得分:0)
这取决于你如何调用你的日常工作。如果end
是数组的长度(如C中常见的那样),则s[end]
不是有效的引用...它是s
之外的一个字符。
此外,!s
不等同于C ++ s.empty
...它测试指针是否为NULL,而不是字符串是否为空 - 为此,使用!*s
, !s[0]
,s[0] == '\0'
,strlen(s) == 0
等
char字符串s不是const。
如果它是一个字符串文字常量,它可能会失败;写入这样的字符串是Undefined Behavior。
答案 1 :(得分:0)
您可以重写以下代码
void reverse(char *s, int start, int end) {
if (!s) return;
char tmp;
if( end >= strlen(s) )
end = strlen(s)-1;
while (start < end) {
tmp = s[end];
*(s + end) = *(s + start);
*(s + start) = tmp;
++start;
--end;
}
}