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;
}
Answers
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作为首地址,当然也不同。
正好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';
,那一行就会发生段错误了。