set*_*thu 8 c string string-literals
我正在尝试反转一个字符串.
这是我试过的代码:
#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);
}
它工作得很好.
为什么第一个代码抛出总线错误或分段错误?
Ray*_*oal 16
发生总线错误是因为在许多(如果不是大多数或所有现代的)C编译器中,字符串文字被分配在只读存储器中.
您正在将字符串反转到位.在您的第一个代码段中,您尝试写入字符串文字.不是个好主意.
在第二种情况下,你malloc'd一个字符串,把它放在堆上.现在可以安全地将该字符串反转到位.
附录
对于询问段错误与总线错误的评论者,这是一个很好的问题.我见过两者.这是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";
然后,常量字符串将被复制到堆栈中.