字符串指针和字符串数组之间的区别 [英] difference between string pointer and string array

查看:124
本文介绍了字符串指针和字符串数组之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写code,以加强我的知识,我得到了分段错误。所以,我也有我有进货(完不完善的知识),在我的知识。这个问题是关于的strtok()。当我运行的第一个code是没有问题的,但在第二次,我得到segmantation故障。什么是我的不完美的知识?感谢您的AP preciated答案。

首先code

 的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;诠释主(){    烧焦海峡[] =TEAM_NAME =费内巴切;
    字符*记号。    令牌= strtok的(STR,=);
    而(令牌!= NULL)
    {
        的printf(%S \\ N标记);
        令牌= strtok的(NULL,=);
    }
  返回0;
}

二code

 的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;诠释主(){    字符*海峡=TEAM_NAME =费内巴切;
    字符*记号。    令牌= strtok的(STR,=);
    而(令牌!= NULL)
    {
        的printf(%S \\ N标记);
        令牌= strtok的(NULL,=);
    }
  返回0;
}


解决方案

您看到字符串你在写入字符串。对于每一个这样的字符串,它不使用物质,会自动的全球空间alloacted储存。当你把它分配到一个数组中 - 你复制它的内容到一个新的内存,该数组中。否则,你只是存储一个指针,它的全球存储器。

所以这个:

  INT的main()
{
    为const char *海峡=TEAM_NAME =费内巴切;
}

等于:

 为const char __unnamed_string [] {'T','E',/*...*/,'\\ 0'};诠释的main()
{
   为const char *海峡= __unnamed_string;
}

和分配字符串数组的时候,是这样的:

  INT的main()
{
    烧焦海峡[] =TEAM_NAME =费内巴切;
}

要这样:

 为const char __unnamed_string [] {'T','E',/*...*/,'\\ 0'};诠释的main()
{
       焦炭海峡[的sizeof(__ unnamed_string)/的sizeof(字符)];       用于(为size_t I(0); I<的sizeof(__ unnamed_string)/的sizeof(char)的; ++ I)
          海峡[I] = __unnamed_string [I]
}

正如你所看到是有区别的。在第一种情况下,你只是存储一个指针,并在第二个 - 你复制整个字符串成当地

注意的:字符串文字是不可编辑,所以你应该在一个恒定存储他们的地址。

在N4296 - §2.13.5 0.8状态:


  

普通字符串文字和UTF-8字符串文字也称为
  为狭窄的字符串。窄字符串文字的类型数组
  ñ为const char,其中n是字符串去连接如下定义的大小,
  并具有静态存储时间


此决定背后的原因,可能是因为这种方式,这样的阵列可以被存储在只读段,从而以某种方式优化方案。有关这个决定看到。

注1 的:

在N4296 - §2.13.5 0.16的状态:


  

在评估一个字符串对象与字符串字面结果
  静态存储持续时间,从给定的字符作为初始化
  上述特定网络版。


这意味着什么我说 - 每一个字符串字面一位不愿透露姓名的全局对象与自己的内容创建

I was writing code to reinforce my knowledge, I got segmentation fault. So, I also got that I have to restock(completing imperfect knowledge) on my knowledge. The problem is about strtok(). When I run the first code there is no problem, but in second, I get segmantation fault. What is my "imperfect knowledge" ? Thank you for your appreciated answers.

First code

#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;
}

Second code

#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;
}

解决方案

You see string literals are the strings you write in "". For every such string, no-matter where it is used, automatically a global space is alloacted to store it. When you assign it to an array - you copy it's content into a new memory, that of the array. Otherwise you just store a pointer to it's global memory storage.

So this:

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

Is equal to:

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

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

And when assigning the string to array, like this:

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

To this:

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];
}

As you can see there is a difference. In the first case you're just storing a single pointer and in the second - you're copying the whole string into local.

Note: String literals are un-editable so you should store their address at a constant.

In N4296 - § 2.13.5 .8 states:

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type "array of n const char", where n is the size of the string as defined below, and has static storage duration

The reason behind this decision is probably because this way, such arrays can be stored in read-only segments and thus optimize the program somehow. For more info about this decision see.

Note1:

In N4296 - § 2.13.5 .16 states:

Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters as specified above.

Which means exactly what I said - for every string-literal an unnamed global object is created with their content.

这篇关于字符串指针和字符串数组之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆