Gui*_*i13 25 c arrays string stack pointers
在编写一个简单的函数来从字符串中删除特定字符时,我遇到了这个奇怪的问题:
void str_remove_chars( char *str, char to_remove)
{
if(str && to_remove)
{
char *ptr = str;
char *cur = str;
while(*ptr != '\0')
{
if(*ptr != to_remove)
{
if(ptr != cur)
{
cur[0] = ptr[0];
}
cur++;
}
ptr++;
}
cur[0] = '\0';
}
}
int main()
{
setbuf(stdout, NULL);
{
char test[] = "string test"; // stack allocation?
printf("Test: %s\n", test);
str_remove_chars(test, ' '); // works
printf("After: %s\n",test);
}
{
char *test = "string test"; // non-writable?
printf("Test: %s\n", test);
str_remove_chars(test, ' '); // crash!!
printf("After: %s\n",test);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我没有得到的是第二次测试失败的原因?对我来说,看起来第一个符号char *ptr = "string";就等于这个:char ptr[] = "string";.
不是这样吗?
cod*_*ict 43
这两个声明是不一样的.
char ptr[] = "string";声明大小的字符数组7和以字符初始化
s,t,r,i,n,g和\0.您可以修改此数组的内容.
char *ptr = "string";声明ptr为字符指针与地址初始化字符串文字 "string"这是只读的.修改字符串文字是一种未定义的行为.你所看到的(seg fault)是未定义行为的一种表现形式.
严格地说,声明char *ptr只保证指向字符类型的指针.字符串构成编译应用程序的代码段的一部分并不罕见,该代码段将由某些操作系统设置为只读.问题在于你正在假设预定义字符串的性质(它是可写的),事实上,你自己从未明确地为该字符串创建内存.编译器和操作系统的某些实现可能允许您执行您尝试执行的操作.
另一方面char test[],根据定义,声明实际上为堆栈中的整个字符数组分配可读写内存.