代码之家  ›  专栏  ›  技术社区  ›  Elle H

strtok-char数组与char指针[重复]

  •  10
  • Elle H  · 技术社区  · 14 年前

    可能重复:
    strtok wont accept: char *str

    当使用 strtok 函数,使用 char * 而不是 char [] 导致分段错误。

    正常运行:

    char string[] = "hello world";
    char *result = strtok(string, " ");
    

    这会导致分段错误:

    char *string = "hello world";
    char *result = strtok(string, " ");
    

    有人能解释导致这种行为差异的原因吗?

    6 回复  |  直到 14 年前
        1
  •  28
  •   aschepler    14 年前
    char string[] = "hello world";
    

    此行初始化 string 成为足够大的字符数组(在本例中 char[12] )它将这些字符复制到本地数组中,就好像您已经写出了

    char string[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0' };
    

    另一条线:

    char* string = "hello world";
    

    不初始化本地数组,它只是初始化本地指针。允许编译器将其设置为指向数组的指针,该数组 你不能换衣服 就像密码是

    const char literal_string[] = "hello world";
    char* string = (char*) literal_string;
    

    C之所以不使用强制转换就允许这样做,主要是为了让古老的代码继续编译。您应该假设源代码中字符串文字的类型是 const char[] ,可以转换为 const char* ,但从不将其转换为 char* .

        2
  •  14
  •   Michael Burr    14 年前

    在第二个示例中:

    char *string = "hello world";
    char *result = strtok(string, " ");
    

    指示者 string 指向无法修改的字符串文本(如 strtok() 希望如此)。

    你可以做一些事情:

    char *string = strdup("hello world");
    char *result = strtok(string, " ");
    

    以便 一串 指向文本的可修改副本。

        3
  •  4
  •   Jerry Coffin    14 年前

    strtok 修改传递给它的字符串(或无论如何尝试)。在第一个代码中,您传递的是一个已初始化为特定值的数组的地址——但是由于它是一个普通的char数组,所以允许修改它。

    在第二个代码中,您传递的是字符串文字的地址。试图修改字符串文字会给出未定义的行为。

        4
  •  3
  •   zwol    14 年前

    在第二种情况下( char * ,字符串在只读内存中。这个 对的 字符串常量的类型为 const char * ,如果使用该类型声明变量,则当您试图修改该变量时,编译器会警告您。出于历史原因,允许使用字符串常量初始化类型的变量 烧焦* 即使它们不能被修改。(有些编译器允许您关闭此历史许可证,例如使用GCC的 -Wwrite-strings )

        5
  •  0
  •   Chris Dodd    14 年前

    第一种情况创建一个(非常量)char数组,该数组足够大,可以容纳字符串,并用字符串的内容对其进行初始化。第二种情况是创建一个char指针,并将其初始化为指向字符串文字,字符串文字可能存储在只读内存中。

    由于strtok想要修改您传递给它的参数所指向的内存,后一种情况会导致未定义的行为(您传递的指针指向(const)字符串文字),因此它不会导致崩溃。

        6
  •  0
  •   Matthieu    14 年前

    因为第二个声明一个指针(可以更改)为常量字符串…

    所以取决于编译器/平台/操作系统/内存映射…“hello world”字符串将存储为常量(在嵌入式系统中,它可能存储在ROM中),尝试修改它将导致该错误。