字符串指针和字符串数组之间的区别

时间:2014-12-27 17:41:59

标签: c arrays string pointers segmentation-fault

我正在编写代码以加强我的知识,我得到了分段错误。所以,我也得知我必须补充(完成不完全的知识)我的知识。问题是关于strtok()。当我运行第一个代码没有问题,但在第二个,我得到segmantation错误。什么是我不完美的知识" ?谢谢你的赞赏。

第一个代码

#include <stdio.h>
#include <string.h>

int main() {



    char str[] = "team_name=fenerbahce";
    char *token;

    token = strtok(str,"=");
    while(token != NULL)
    {
        printf("%s\n",token);
        token = strtok(NULL,"=");
    }
  return 0;
}

第二个代码

#include <stdio.h>
#include <string.h>

int main() {



    char *str= "team_name=fenerbahce";
    char *token;

    token = strtok(str,"=");
    while(token != NULL)
    {
        printf("%s\n",token);
        token = strtok(NULL,"=");
    }
  return 0;
}

3 个答案:

答案 0 :(得分:3)

来自strtok -

  

这个功能是破坏性的:它写了&#39; \ 0&#39;字符串str的元素中的字符。特别是,字符串文字不能用作strtok的第一个参数。

在第二种情况下,str是一个字符串文字,它位于只读内存中。任何修改字符串文字的尝试都会导致未定义的行为。

答案 1 :(得分:1)

char *str= "team_name=fenerbahce";
char str[]= "team_name=fenerbahce";

“不完美”的知识是关于数组和指针之间的区别!它是关于使用指针创建字符串时无法修改的内存。 创建字符串时,您会分配一些内存来存储这些值(字符串的字符)。在接下来的几行中,当我谈到“开始时分配的内存”时,我会参考这个。

使用数组创建字符串时,您将创建一个数组,该数组包含与字符串相同的字符。所以你会分配更多的内存。

使用指针创建字符串时,您将指向指向包含该字符串的内存地址(在开始时分配的字符串)。

您必须假设在开始时创建的内存不可写(这就是为什么您将有未定义的行为,这意味着大多数时候都会出现分段错误,所以不要这样做)。 相反,当您创建数组时,该内存将是可写的!这就是为什么你只能在这种情况下使用像strtok这样的命令进行修改

答案 2 :(得分:1)

你看到字符串文字是你在“”中写的字符串。对于每个这样的字符串,无论在何处使用它,都会自动地全局空间来存储它。将其分配给数组时 - 将其内容复制到新数据库的内存中。否则,您只需存储指向其全局内存存储器的指针。

所以这个:

int main()
{
    const char *str= "team_name=fenerbahce";
}

等于:

const char __unnamed_string[] { 't', 'e', /*...*/, '\0' };

int main()
{
   const char *str= __unnamed_string;
}

将字符串分配给数组时,如下所示:

int main()
{
    char str[] = "team_name=fenerbahce";
}

对此:

const char __unnamed_string[] { 't', 'e', /*...*/, '\0' };

int main()
{
       char str[sizeof(__unnamed_string) / sizeof(char)];

       for(size_t i(0); i < sizeof(__unnamed_string) / sizeof(char); ++i)
          str[i] = __unnamed_string[i];
}

正如您所看到的,存在差异。在第一种情况下,你只是存储一个指针而在第二种情况下 - 你将整个字符串复制到本地。

注意:字符串文字是不可编辑的,因此您应将其地址存储在常量中。

在N4296 - §2.13.5.8中指出:

  

也引用普通的字符串文字和UTF-8字符串文字   作为窄字符串文字。窄字符串文字的类型为“数组”   of n const char“,其中n是下面定义的字符串的大小,   并具有静态存储持续时间

这个决定背后的原因可能是因为这样,这样的数组可以存储在只读段中,从而以某种方式优化程序。有关此决定的更多信息see

注1

在N4296 - §2.13.5.16中指出:

  

评估字符串文字会产生字符串文字对象   静态存储持续时间,从给定字符初始化为   以上具体说明。

这正是我所说的 - 对于每个字符串文字,一个未命名的全局对象是用它们的内容创建的。