2011-09-18 101 views
8

我想反转一个字符串。总线错误故障排除

这是我尝试的代码:

#include<stdio.h> 
#include<string.h> 

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); 
} 

它完美的罚款。

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

+1

请重新格式化您的代码。 –

+0

尽量尝试格式化,但我真的不知道如何让它们对齐。 – sethu

+1

请格式化您的代码,并用四个空格将其缩进。 – SLaks

回答

16

总线错误的发生是因为在很多(如果不是大多数或全部现代的)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 

在其他操作系统/编译器,你可能确实得到段错误。

+0

我认为试图写只读内存会导致段错误,而不是总线错误?或者是操作系统特定的? – cHao

+0

我见过两个! –

+0

你必须在那里做一些古怪的东西。 :)只有我见过一次巴士错误的时候,主板坏了。 – cHao

1

"I am a good boy"的形式指定的字符数组通常是不变的 - 您不能修改它们。这就是为什么你的第一个变种崩溃。第二个不会,因为您制作数据的副本,然后对其进行修改。

6

将其复制到堆是一种选择。但是,如果你只是想分配一个本地(堆栈)数组,你可以这样做:

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

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

0

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

编辑:你malloc()和复制你正在玩的原始字符串和ptr的副本不是'常量字符*'类型,而是'char * ptr',而不是抱怨。

0

用C编译++(克++)示出了一个非常量char *,其被设计为防止这种错误分配一个字符串文字的弃用:

[email protected]:~/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 *可防止赋值为文字字符串。

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