我正在尝试对c-string进行冒泡排序 - 请参阅下面的函数。目的是根据ASCII码对字符进行排序。
编译器在运行时才会抱怨,此时我会遇到分段错误。我运行了gdb,程序运行正常,直到第12行。在第12行,gdb调试器声明'处理gdb-inferior已杀死'。
为什么第12行不正确?我在程序的其他地方遇到过这个问题 - 无法将字符分配给c字符串的元素。我知道strcpy()需要字符串赋值,但是对于特定的元素,我认为它没问题。任何帮助很多人赞赏。
1. void bubblesort(char *str)
2. {
3. int length = strlen(str);
4.
5. for (int i = length - 1; i > 0; i--)
6. {
7. for (int j = 0; j < i; j++)
8. {
9. if (str[j] > str[j + 1])
10. {
11. char temp = str[j + 1];
12. str[j + 1] = str[j];
13. str[j] = temp;
14. }
15. }
16. }
17. return;
18. }
答案 0 :(得分:5)
我已经测试了你的代码并且它运行得很好。我确实有2个理论来解释为什么你的代码片段不起作用。
理论一:你正在尝试写一个字符串文字,这需要像这样的一行:
char* str = "abc";
你的操作系统很可能把“abc”放在一个单独的只读页面中,当你在12处写入变量时,这将导致一个SEGFAULT。
理论2:
错误很可能发生在strlen函数中,它需要一个以空字符结尾的字符串。例如,Free BSD版本如下所示:
size_t strlen(const char * str)
{
const char *s;
for (s = str; *s; ++s) {}
return(s - str);
}
想象一下,你将“abc”存储在内存中而没有空终止字节。 strlen将查找字母'c',直到找到单个\ 0(0x00)字节。此内存只能是只读的,在这种情况下,当您尝试写入时,会在第12行创建SEGFAULT。 (所有以前的访问都是只读的)
答案 1 :(得分:0)
我想我解决了自己的问题...
调用这样的函数时:
foo(“some string”);
假设形式的foo()的定义:
foo(char * str){.......}
会给出“已弃用的转化”警告。这很烦人但可以忽略,除非你想在函数foo中修改str。自动转换将“some string”转换为CONSTANT字符指针而不是常规字符指针。无论你在声明/定义中写入foo(char * str)或foo(const char * str),它都会这样做 - 如果你写前者,它只会发出警告。
总之,在这种情况下编写foo(const char * str)是更好的风格,如果必须在函数内修改str,那么应该在foo函数中创建变量的副本。