I have a small C++ function which reverses a string in place:
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;
}
}
This function works fine. However, when I rewrite it in c as below, I came across a segment fault on statement 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 }
Driver program that calls the function:
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);
}
I use gcc v 4.6.1 to compile my program. When stepping through the code with gdb, the program crashes at runtime with segmentation fault.
The char string s is not a const. Can someone please suggest what’s going on here? How do I fix this issue. Thanks.
Update:
The reverse2 function is called on a string literal. The problem is I was trying to modify the string literal. As Jim and H2CO3 pointed out, this is an undefined behavior.
Now what’s the exact difference between a string object (a) initialized with a string literal and a string literal (b)?
It depends on how you invoke your routine. If
endis the length of the array, as is common in C, thens[end]is not a valid reference … it’s one character beyonds.Also,
!sis not equivalent to C++s.empty… it tests whether the pointer is NULL, rather than whether the string is empty — for that, use!*s,!s[0],s[0] == '\0',strlen(s) == 0, etc.It could fail anyway if it’s a string literal constant; writing to such a string is Undefined Behavior.