理解C字符串& C ++中的字符串文字

时间:2011-10-06 03:29:08

标签: c++ arrays string string-literals c-strings

我想问一些关于字符串文字和C字符串的问题。

所以,如果我有这样的事情:

char cstr[] = "c-string";

据我所知,字符串文字是在内存中创建的,带有一个终止空字节,例如从地址0xA0开始到0xA9结束,从那里返回地址和/或转换为char []类型然后指向地址。

执行此操作是合法的:

for (int i = 0; i < (sizeof(array)/sizeof(char)); ++i)
    cstr[i] = 97+i;

所以从这个意义上说,只要字符串文字被转换为char []类型,它们是否能够被修改?

但是对于常规指针,我已经明白当它们指向内存中的字符串文字时,它们无法修改内容,因为大多数编译器在一些下界地址空间中将分配的内存标记为“只读”对于常数。

char * p = "const cstring";
*p = 'A'; // illegal memory write

我想我想要理解的是为什么char *类型不允许指向像数组那样的字符串文字并修改它们的常量?为什么字符串文字不像char []那样被转换为char *?如果我在这里有错误的想法或完全关闭,请随时纠正我。

4 个答案:

答案 0 :(得分:4)

你缺少的是一个小编译器魔术:

char cstr[] = "c-string"; 

实际执行如下:

char *cstr = alloca(strlen("c-string")+1);
memcpy(cstr,"c-string",strlen("c-string")+1);

你没有看到这一点,但它或多或少是代码编译的内容。

答案 1 :(得分:2)

char cstr[] = "something";声明自动数组 已初始化 到字节'','o','m',......

另一方面,

char * cstr = "something";声明一个字符指针初始化为文字“某事物”的 地址

答案 2 :(得分:1)

char cstr[] = "c-string";

将“c-string”复制到堆栈中的char数组中。写入此记忆是合法的。

char * p = "const cstring";
*p = 'A'; // illegal memory write

像“c-string”和“const cstring”这样的文字字符串存在于二进制文件的数据段中。该区域是只读的。 p以上指向此区域的内存,写入该位置是非法的。从C ++ 11开始,这比以前强制执行,因为必须使其成为const char* p

相关问题here

答案 3 :(得分:1)

在第一种情况下,您要创建一个实际的字符数组,其大小由您使用(8 + 1字节)初始化它的文字大小决定。 cstr变量在堆栈上分配内存,字符串文字的内容(在代码中位于其他地方,可能在内存的只读部分)是复制到这个变量。

在第二种情况下,局部变量p也在堆栈上分配了内存,但其内容将是您正在初始化它的字符串文字的地址。 / p>

因此,由于字符串文字可能位于只读存储器中,因此尝试通过p指针进行更改通常是不安全的(您可能会相处,或者您可能不会) 。另一方面,您可以对cstr数组执行任何操作,因为这是您刚才从文字初始化的本地副本。

(只需注意一点:cstr变量属于类型的char ,在大多数情况下,这会转换为指向该数组第一个元素的指针。对此的例外可能是例如sizeof运算符:这个运算符计算整个数组的大小,而不仅仅是指向第一个元素的指针。)