void reverse(char* str) 引发的问题

我们的问题是:用 C 或 C++ 实现 void reverse(char* str) 函数。

第一版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string.h>
using namespace std;
void reverse(char* str)
{
truesize_t l = strlen(str) - 1;
truechar tmp;
truefor (int i = 0; i < l; ++i, --l)
true{
truetruetmp = str[l];
truetruestr[l] = str[i];
truetruestr[i] = tmp;
true}
}
int main(int argc, char const *argv[])
{
truechar* str = "hello world!";
truereverse(str);
truecout << str;
truereturn 0;
}

编译通过,运行时错误:Segmentation fault (core dumped)什么是Segmentation fault(Core Dump)?

Segmentation fault (core dumped)

Google 一下,发现问题出在 char str=“STRING”char str[] = “STRING” 的不同上【stackoverflow:[Difference between char str=“STRING” and char str] = “STRING”?

char ptr[] = “string”; 定义了一个大小为 7 ,初始化为 s ,t,r,i,n,g 和 \0 的 char 数组,数组内容可以修改

char ptr = “string”; 定义了一个初始化为 string literal (“string”) 的 *只读 char 指针,修改 string literal 是未定义行为,具体表现就是出现 Segmentation fault (core dumped)。

那么把 char ptr = “string”; 改为 char ptr = “string”; 就 ok 了呢?用空字符串测试下,发现再次出现 Segmentation fault (core dumped)

原因是 size_t 实际上是 unsigned int / long unsigned int (64x),空字符串将使 size_t l = strlen(str) - 1; 中 l 变为 max(int) - 1,加入对空字符串的判断,完整如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string.h>
using namespace std;
void reverse(char* str)
{
trueif (str && strlen(str))
true{
truetruesize_t l = strlen(str) - 1;
truetruechar tmp;
truetruefor (int i = 0; i < l; ++i, --l)
truetrue{
truetruetruetmp = str[l];
truetruetruestr[l] = str[i];
truetruetruestr[i] = tmp;
truetrue}
true}
}
int main(int argc, char const *argv[])
{
truechar str[] = "";
truereverse(str);
truecout << str;
truereturn 0;
}

当然,你可以使用 int 来避免这个问题,总之,细节是魔鬼。