为了账号安全,请及时绑定邮箱和手机立即绑定

char * str =“ STRING”和char str [] =“ STRING”之间的区别?

/ 猿问

char * str =“ STRING”和char str [] =“ STRING”之间的区别?

忽然笑 2019-10-11 10:56:14

在编写一个简单的函数以从字符串中删除特定字符的过程中,我遇到了一个奇怪的问题:


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;

}

我不明白为什么第二项测试失败了?对我来说,它看起来像第一表示char *ptr = "string";相当于这一个:char ptr[] = "string";。


是不是这样


查看完整描述

3 回答

?
湖上湖

这两个声明不相同。


char ptr[] = "string";声明大小的字符数组7和以字符初始化

s,t,r,i,n,g和\0。您可以修改此数组的内容。


char *ptr = "string";声明ptr为一个char指针,并使用字符串型字符串常量的 地址将其初始化"string"为只读。修改字符串文字是未定义的行为。您所看到的(段错误)是未定义行为的一种体现。


查看完整回答
反对 回复 2019-10-11
?
慕工程0101907

严格说来,声明char *ptr只能保证您指向字符类型。字符串形成已编译应用程序的代码段的一部分并不少见,该代码段将被某些操作系统设置为只读。问题在于,实际上您从未自己为该字符串显式创建内存时,您就对预定义字符串的性质(它是可写的)进行了假设。编译器和操作系统的某些实现可能允许您执行尝试做的事情。


另一方面char test[],在这种情况下,根据定义,声明实际上为堆栈上的整个字符数组分配了可读写的内存。


查看完整回答
反对 回复 2019-10-11
?
函数式编程

char *test = "string test";是错的,应该是const char*。该代码仅出于向后兼容性的原因进行编译。指向的内存const char*是只读内存,每当您尝试对其进行写操作时,它将调用未定义的行为。另一方面,在堆栈上char test[] = "string test"创建可写字符数组。就像您可以写入的任何其他常规局部变量一样。


查看完整回答
反对 回复 2019-10-11

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信