反转字符串时碰到的问题
2020-12-28 13:17:54

现象

对一个字符串Hello做反转

很简单的题,没有多余的考虑,直接通过指针进行反转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <string.h>

int
main()
{
char *str = "hello";
printf("%s\n", str);

int start_ptr = 0, end_ptr = strlen(str) - 1;
while (start_ptr < end_ptr) {
char temp = *(str + start_ptr);
*(str + start_ptr) = *(str + end_ptr);
*(str + end_ptr) = temp;
++start_ptr;
--end_ptr;
}

printf("%s\n", str);

return 0;
}

执行时显示段错误

1
2
3
4
5
6
7
8
9
Reading symbols from test...
(gdb) r
Starting program: /home/z/test
hello

Program received signal SIGSEGV, Segmentation fault.
main () at test.c:13
13 *(str + start_ptr) = *(str + end_ptr);
(gdb)

解决

GDB 报出的错误是非法的内存使用。考虑到功能要求非常简单,不可能逻辑错误,也没有内存越界的情况,看了一下人家的代码,逻辑也是一样的。但是定义字符串时别人是用char [],我是char *,考虑这方面的错误

于是翻出来学 C 语言时的书,瞄了一眼就想给自己一个嘴巴子

char []是在栈区里, char *是一个字符串常量,在静态数据区,错误显而易见

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
28
29
30
31
32
#include <stdio.h>
#include <string.h>

int
reverseStr(char *str)
{
// 成功返回1,失败返回0
if (str == NULL) return 0;

int start_ptr = 0, end_ptr = strlen(str) - 1;
while (start_ptr < end_ptr) {
char temp = *(str + start_ptr);
*(str + start_ptr) = *(str + end_ptr);
*(str + end_ptr) = temp;
++start_ptr;
--end_ptr;
}
return 1;
}

int
main()
{
char str[] = "hello";
printf("%s\n", str);

reverseStr(str);

printf("%s\n", str);

return 0;
}

延申

如果如以上代码,那无法处理字符串常量。考虑到别人可能传入一个字符串常量,可以考虑申请内存空间,利用栈,或者尾指针,来逐个拷贝

或者判断参数是栈区数据还是静态数据区数据(这应当如何判断呢),选择不同的反转方法