我们的问题是:用 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)? 】
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 来避免这个问题,总之,细节是魔鬼。