字符串指针和字符串数组之间的区别 [英] difference between string pointer and string array
问题描述
我在写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屋!