【问题标题】:char* and char[] are not same type? [duplicate]char* 和 char[] 不是同一类型? [复制]
【发布时间】:2012-11-16 10:14:58
【问题描述】:

可能重复:
Why do I get a segmentation fault when writing to a string?

我的 C 代码遇到了一个奇怪的问题。我正在尝试使用 strtok 函数拆分字符串,但出现访问冲突异常。这是我的代码:

char *token;
char *line = "LINE TO BE SEPARATED";
char *search = " ";
token = strtok(line, search); <-- this code causes crash

但是,如果我将 char *line 更改为 char line[],一切都会按预期进行,并且不会出现任何错误。

任何人都可以解释为什么我使用 strtok 会出现这种(对我来说很奇怪)行为?我认为 char* 和 char[] 是相同且精确的类型。

更新

我正在使用 MSVC 2012 编译器。

【问题讨论】:

  • 您的编译器应该拒绝或至少警告转换为char*(在 C++11 中不再允许)。调高警告级别。
  • @hmjd 类型转换在 C 和 C++ 中的行为不一定相同。
  • @Gorpik,我问的唯一原因是似乎没有 C++ 特定代码。如果是 C++,那么有更好的方法来做到这一点(例如使用流)。
  • @hmjd 你说得对,我修改了标签。

标签: c


【解决方案1】:
char *s = "any string"

是指向字符串或字符数组的指针的定义。在上面的例子中s 指向一个常量字符串

char s[] = "any string"

是 char(s) 数组的定义。在上面的例子中s 是一个字符数组,其中包含字符{'a','n','y',' ','s','t','r,'i','n','g','\0'}

strtock 更改输入字符串的内容。它用'\0' (null) 替换字符串中的分隔符。

因此,您不能将strtok 与这样的常量字符串一起使用:

char *s="any string"

您可以将 strtok 与动态内存或静态内存一起使用,例如:

char *s = malloc(20 * sizeof(char)); //dynamic allocation for string
strcpy(s,"any string");


char s[20] = "any string"; //static allocation for string
char s[] = "any string"; //static allocation for string

【讨论】:

    【解决方案2】:

    回答您的问题:char* and char[] are not same type?

    这个:

    char *line = "LINE TO BE SEPARATED";
    

    是在只读内存中定义的字符串文字。您无法更改此字符串。

    但是:

    char line[] = "LINE TO BE SEPARATED";
    

    现在是一个字符数组(引用的文本被复制到数组中)放置在堆栈上。您可以修改此数组中的字符。

    所以它们都是字符数组,只是放在内存的不同部分。

    【讨论】:

      【解决方案3】:

      "LINE TO BE SEPARATED" 分配给char *line 时,您使line 指向写入程序可执行文件中的常量字符串。您无权对其进行修改。您应该将这类变量声明为const char *

      当声明为char[] 时,您的字符串被声明在函数的堆栈中。因此,您可以对其进行修改。

      【讨论】:

        【解决方案4】:

        strtok() 修改它解析的字符串。如果你使用:

        char* line = "...";
        

        然后正在修改字符串文字,这是未定义的行为。使用时:

        char[] line = "...";
        

        然后正在修改字符串文字的副本

        【讨论】:

        • 正确;一个快速的解决方法是写char *line = strdup("LINE TO BE SEPARATED");,但记得在之后释放内存。作为对张贴者的说明,gcc 在编译时会对此发出警告。对于 MSVC,您应该启用所有警告以捕获此类错误。
        • @csl,关于警告的合理建议(/W4/WX 用于 VC)。
        • @csl - 请注意 strdup 不是标准 C 或标准 C++ 的一部分。
        • for char* line = "..."; 我宁愿说:正在修改只读(或 const)字符串文字。只是为了更清楚。
        • @PeteBecker 谢谢,我不知道!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-27
        • 2011-12-14
        • 1970-01-01
        • 2013-01-10
        • 2013-04-01
        • 2021-08-28
        • 1970-01-01
        相关资源
        最近更新 更多