为什么这个字符串反转C代码会导致分段错误?
我正试图编写代码来反转字符串(我只是想在C编程和指针操作方面做得更好),但我不明白为什么我会得到:为什么这个字符串反转C代码会导致分段错误?,c,string,segmentation-fault,C,String,Segmentation Fault,我正试图编写代码来反转字符串(我只是想在C编程和指针操作方面做得更好),但我不明白为什么我会得到: #包括 无效反向(字符*s); int main(){ char*s=“teststring”; 反面; 返回0; } 无效反向(字符*s){ int i,j; 焦炭温度; 对于(i=0,j=(strlen(s)-1);i
#包括
无效反向(字符*s);
int main(){
char*s=“teststring”;
反面;
返回0;
}
无效反向(字符*s){
int i,j;
焦炭温度;
对于(i=0,j=(strlen(s)-1);i
导致分段错误的是第2行和第3行。我知道可能有更好的方法可以做到这一点,但我感兴趣的是找出我的代码中导致分段错误的具体原因
更新:我已按要求包含调用函数。您的代码可能由于多种原因而出现错误。以下是我想到的
const char*
,而不是char*
。您需要做的是将一个可修改的字符串传递到该缓冲区
快速示例:
char* pStr = strdup("foobar");
reverse(pStr);
free(pStr);
没有办法仅仅从代码中说出来。最有可能的情况是,您正在传递一个指针,该指针指向无效内存、不可修改内存或其他类型的内存,这些内存无法按照您在此处处理的方式进行处理 如何调用函数 添加:您正在传递一个指向字符串文本的指针。字符串文字是不可修改的。不能反转字符串文字 而是传入指向可修改字符串的指针
char s[] = "teststring";
reverse(s);
这已经在这里解释得透不过气来了<代码>“teststring”是字符串文字。字符串文字本身是不可修改的对象。实际上,编译器可能(也将)把它放在只读内存中。当您初始化这样的指针时
char *s = "teststring";
指针直接指向字符串文字的开头。在一般情况下,任何修改s
所指向内容的尝试都将被视为失败。你可以读,但不能写进去。因此,强烈建议仅使用指向常量变量的指针指向字符串文本
const char *s = "teststring";
但是当您将s
声明为
char s[] = "teststring";
您将得到一个完全独立的数组s
,该数组位于普通可修改内存中,它只是用字符串literal初始化的。这意味着独立的可修改数组s
将从字符串文本中复制其初始值。在此之后,s
数组和字符串文本继续作为完全独立的对象存在。文本仍然是不可修改的,而s
数组是可修改的
基本上,后一种声明在功能上等同于
char s[11];
strcpy(s, "teststring");
你在测试这样的东西吗
int main() {
char * str = "foobar";
reverse(str);
printf("%s\n", str);
}
这使str成为字符串文字,您可能无法编辑它(我是segfaults)。如果您定义char*str=strdup(foobar)它应该可以正常工作(对我来说是这样的)。您使用的是哪种编译器和调试器?使用gcc和gdb,我将使用-g标志编译代码,然后在gdb中运行它。当它出现故障时,我只需执行一个backtrace(gdb中的bt命令),看看哪一行是导致问题的原因。此外,我将一步一步地运行代码,同时“观察”gdb中的指针值,并知道问题的确切位置 祝你好运。我想s不是空终止的,所以不能工作。因此,for迭代的行为不是您所期望的。 因为strlen的结果将优于s长度,所以您将在不应该在的内存中写入 此外,s指向由只读内存保存的常量字符串。您不能修改它。尝试使用gets函数初始化s,如示例中所示请参见C FAQ列表中的: 这些初始化之间有什么区别
char a[] = "string literal";
char *p = "string literal";
如果我试图给p[I]
分配一个新值,我的程序就会崩溃
答复:
字符串文字(C源代码中双引号字符串的正式术语)可以用两种稍有不同的方式使用:
作为字符数组的初始值设定项,如在char a[]
的声明中,它指定该数组中字符的初始值(如有必要,还指定其大小)
在其他任何地方,它都会变成一个未命名的静态字符数组,此未命名数组可能存储在只读内存中,因此不必修改。在表达式上下文中,数组像往常一样立即转换为指针(参见第6节),因此第二个声明初始化p
以指向未命名数组的第一个元素
有些编译器有一个开关控制字符串文字是否可写(用于编译旧代码),有些编译器可能有选项使字符串文字被正式视为const char
的数组(以便更好地捕捉错误)
(强调矿山)
另请参见。您的声明完全错误:
char* s = "teststring";
“teststring”存储在代码段中,与代码一样,代码段是只读的。s是指向“teststring”的指针,同时,您试图更改只读内存范围的值。因此,分割错误
但是:
char s[] = "teststring";
s用“teststring”初始化,它当然在代码段中,但在本例中,还有一个额外的复制操作正在进行 正如上面提供的一些答案一样,字符串内存是只读的。但是,有些编译器提供了使用可写字符串进行编译的选项。例如,使用
char s[] = "teststring";