使用指针修改字符串时发生分段错误?
上下文
我正在学习C,我正在尝试使用指针来反转字符串。 (我知道你可以使用一个数组;这更多的是学习指针。)
问题
尝试运行下面的代码时,我不断遇到分段错误。 GCC似乎不喜欢*end = *begin;
线。 这是为什么?
特别是因为我的代码几乎与另一个问题中讨论的非邪恶C函数相同
#include #include void my_strrev(char* begin){ char temp; char* end; end = begin + strlen(begin) - 1; while(end>begin){ temp = *end; *end = *begin; *begin = temp; end--; begin++; } } main(){ char *string = "foobar"; my_strrev(string); printf("%s", string); }
传递给函数的参数存在一个问题:
char *string = "foobar";
这是在只读部分中分配的静态字符串。 当您尝试用它覆盖它时
*end = *begin;
你会得到段错误。
试试吧
char string[] = "foobar";
你应该注意到一个区别。
关键点在于,在第一种情况下,字符串存在于只读段中,并且仅使用指向它的指针,而在第二种情况下,在堆栈上保留具有适当大小的字符数组和静态字符串(其中永远存在)被复制到其中。 之后,您可以自由修改arrays的内容。
您还可以使用字符串末尾的空字符来交换字符串中的字符,从而避免使用任何额外的空格。 这是代码:
#include void reverse(char *str){ int length=0,i=0; while(str[i++]!='\0') length++; for(i=0;i
在您的代码中,您有以下内容:
*end--; *begin++;
只做纯粹的运气,这是正确的事情(实际上,原因是运算符优先)。 看起来你打算让代码真正做到
(*end)--; (*begin)++;
这是完全错误的。 你拥有它的方式,操作就像
- 减少
end
然后取消引用它 - 增量
begin
然后取消引用它
在这两种情况下,取消引用都是多余的,应该删除。 你可能想要的行为
end--; begin++;
这些是推动开发人员瘫痪的因素,因为他们很难追查。
这将是适当的并使用指针
#include #include #include void reve(char *s) { for(char *end = s + (strlen(s) - 1); end > s ; --end, ++s) { (*s) ^= (*end); (*end) ^= (*s); (*s) ^= (*end); } } int main(void) { char *c = malloc(sizeof(char *) * 250); scanf("%s", c); reve(c); printf("\nReverse String %s", c); }
改变char *string = "foobar";
to char string[] = "foobar";
。 问题是char *
指向只读内存然后尝试修改导致分段错误。
这使得一个小的(ish)递归函数通过将值存储在堆栈的路上并在返回的路上(返回)将指针递增到字符串的开头(* s)来工作。
聪明的代码,但在堆栈使用方面很糟糕。
#include char *reverse_r(char val, char *s, char *n) { if (*n) s = reverse_r(*n, s, n+1); *s = val; return s+1; } int main(int argc, char *argv[]) { char *aString; if (argc < 2) { printf("Usage: RSIP \n"); return 0; } aString = argv[1]; printf("String to reverse: %s\n", aString ); reverse_r(*aString, aString, aString+1); printf("Reversed String: %s\n", aString ); return 0; }
这是我的原地C字符串反转版本。
#include #include int main (int argc, const char * argv[]) { char str[] = "foobar"; printf("String:%s\n", str); int len = (int)strlen(str); printf("Lenth of str: %d\n" , len); int i = 0, j = len - 1; while(i < j){ char temp = str[i]; str[i] = str[j]; str[j] = temp; i++; j--; } printf("Reverse of String:%s\n", str); return 0; }
下面,您可以看到此问题的代码:
#include #include char* strRev(char* str) { char *first,*last; if (!str || !*str) return str; size_t len = strlen(str); for (first = str, last = &str[len] - 1; first < last ; first++, last--) { str[len] = *first; *first = *last; *last = str[len]; } str[len] = '\0'; return str; } int main() { char test[13] = "A new string"; std::cout << strRev(test) << std::endl; return 0; }