C-Segmentation fault (core dumped)


下面程序是用C语言写的逆置字符串,我觉得逆置函数没问题,但是传参数的不同会导致运行时的Segmentation fault (core dumped),什么原因呢?


 #include <stdio.h>

void reverse(char *str){
   char *end=str;
   char tmp;
   if(str){
     while(*end){
        ++end;
     }
     --end;
     while(str<end){
       tmp=*str;
       *str++=*end;
       *end--=tmp;
   }
   }
}

int main()
{
     char str[][5]={"abcd","","ab","a"};
     int i;
     for(i=0;i<4;i++)
     {
     printf("%s",str[i]);
     reverse(str[i]);   //这种方式没有问题
     printf("%s\n",str[i]);
     }
     char str1[]="abcd";
     char *str2="abcd";
     reverse(str1);
     reverse(str2);   //这种方式会出现core dumped
     printf("%s\n",str1);
     printf("%s\n",str2);
     return 0;
}


update:感谢@spacewander的解答,后来亲自测试了下:


 #include <stdio.h>

void modify(char *str){
    str[2]='a';
}
int main(){
    char s[]="test";
    char *c="test";
    modify(s);
    printf("%s\n",s);//正常
    modify(c);      //core dumped
    printf("%s\n",c);
    return 0;
}

c C++ 内存

暗暗的布丁 11 years, 8 months ago

char *str2="abcd";
str2不能被修改

青龙刀削面 answered 11 years, 8 months ago

char str1[]="abcd";
char *str2="abcd";

str1和str2的意义是不同的。跑代码的时候,内存通常被分为堆区,栈区,代码区,全局和静态变量区,常量区等。str1是普通的字符数组,是一个变量,如果它是全局的,就放在全局和静态区;如果是它是局部的,就放在栈里。str2是个字符串指针,它指向一段字符串常量“abcd”,这段字符串常量放在常量区,不能修改。

你可以把str1看成一个指针,那是因为数组名就是数组的首地址,地址就是指针,仅此而已。如果你再声明一个char *str3 = "abcd";你会发现str2和str3是相等的,因为它们都指向同一个字符串常量,那个常量的位置固定,str2和str3自然相等。但是如果你再声明一个char str4[] = "abcd"; 你会发现str1和str4不相等,原因就是这两个字符数组存储在不同的位置,str1和str4作为首地址,当然也不同。

taylor answered 11 years, 8 months ago

正好StackOverflow上有一个问题是关于"char s[] 和 char *s"的区别:
http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c

char *s所赋值的变量,会被编译器放在内存中栈的只读数据段。对于直接用s所做的修改,会因为错误的内存访问而发生段错误。

证明:
你在 char *str2="abcd"; 下添加一行 str2[0] = 'b'; ,那一行就会发生段错误了。

新垣结衣D颜 answered 11 years, 8 months ago

Your Answer