0

我有一个小的 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 所指出的,这是一种未定义的行为。

现在用字符串文字初始化的字符串对象(a)和字符串文字(b)之间的确切区别是什么?

4

2 回答 2

0

这取决于你如何调用你的例程。如果end是数组的长度,这在 C 语言中很常见,则s[end]不是有效的引用……它是超出 的一个字符s

此外,!s不等同于 C++ s.empty...它测试指针是否为 NULL,而不是字符串是否为空——为此,使用!*s, !s[0], s[0] == '\0',strlen(s) == 0等。

char 字符串 s 不是 const。

如果它是字符串文字常量,它无论如何都可能失败;写入这样的字符串是未定义的行为。

于 2012-09-21T04:27:14.367 回答
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;
  } 
} 
于 2012-09-21T04:37:51.200 回答