总线错误故障排除

我正在尝试反转一个字符串。

这是我试过的代码:

#include #include int main(){ char *c="I am a good boy"; printf("\n The input string is : %s\n",c); printf("\n The length of the string is : %d\n",strlen(c)); int i,j; char temp; int len=strlen(c); for(i=0,j=len-1;i<=j;i++,j--) { temp=c[i]; c[i]=c[j]; c[j]=temp; //printf("%c\t%c\n",*(c+i),*(c+(len-i-1))); } printf("\n reversed string is : %s\n\n",c); } 

代码输出Bus error : 10

但是,如果我重写相同的代码:

 int main(void) { char *str; str="I am a good boy"; int i,j; char temp; int len=strlen(str); char *ptr=NULL; ptr=malloc(sizeof(char)*(len)); ptr=strcpy(ptr,str); for (i=0, j=len-1; i<=j; i++, j--) { temp=ptr[i]; ptr[i]=ptr[j]; ptr[j]=temp; } printf("The reverse of the string is : %s\n",ptr); } 

它工作得非常好。

为什么第一个代码抛出总线错误或分段错误?

发生总线错误是因为在许多(如果不是大多数或所有现代的)C编译器中,字符串文字被分配在只读存储器中。

您正在将字符串反转到位。 在您的第一个代码段中,您尝试写入字符串文字。 不是个好主意。

在第二种情况下,你malloc了一个字符串,把它放在堆上。 现在可以安全地将该字符串反转到位。

附录

对于询问有关段错误与总线错误的评论者,这是一个很好的问题。 我见过两者。 这是mac上的总线错误:

 $ cat bus.c char* s = "abc"; int main() {s[0]='d'; return 0;} $ gcc --version bus.c && ./a.out i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Bus error 

在其他操作系统/编译器上,您可能确实会遇到段错误。

将其复制到堆是一种选择。 但是,如果您只想分配本地(堆栈)数组,则可以执行以下操作:

 char str[] = "I am a good boy"; 

然后,常量字符串将被复制到堆栈中。

"I am a good boy"forms指定的字符数组通常是不变的 – 你无法修改它们。 这就是你的第一个变种崩溃的原因。 第二个没有,因为你复制了数据然后修改它。

char * str =“我是个好孩子”; 作为文字处理并尝试修改它将导致总线错误。 它相当于const char * str =“我是一个好孩子”,即指向常量字符串并尝试修改常量字符串的指针是不允许的。

编辑:当你malloc()和复制你正在播放原始字符串的副本,而ptr不是’const char *’类型,而是’char * ptr’并且不会抱怨。

使用c ++(g ++)进行编译显示不支持将字符串文字分配给非const char *,以防止出现此错误:

 ed@bad-horse:~/udlit_debug$ g++ ../buserr.cpp ../buserr.cpp: In function 'int main()': ../buserr.cpp:5:13: warning: deprecated conversion from string constant to 'char*' ../buserr.cpp:7:61: warning: format '%d' expects type 'int', but argument 2 has type 'size_t' 

相关警告在第5行。

如上所示,将声明更改为const char *会阻止分配到文字字符串中。

这也是为什么你不应该忽略警告的一个教训。