我想知道为什么这可以工作而不必为字符串绑定内存

时间:2017-05-10 11:26:28

标签: c string pointers string-literals

大家好,我最近选择了C编程,但我仍然坚持理解指针。据我所知,要在指针中存储一个值,你必须绑定内存(使用malloc)你想要存储的值的大小。鉴于此,下面的代码不应该工作,因为我没有分配11个字节的内存来存储我的11字节大小的字符串,但由于某种原因超出我的理解它完全正常。

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

int main(){

  char *str = NULL;

  str = "hello world\0";
  printf("filename = %s\n", str);
  return 0;
}

5 个答案:

答案 0 :(得分:3)

在这种情况下

 str = "hello world\0";

str指向使用chars初始化的"hello world\0"数组的第一个元素的地址。换句话说,str指向“字符串文字”。

根据定义,数组已分配,第一个元素的地址必须为“有效”。

引用C11,章节§6.4.5,字符串文字

  

在转换阶段7中,将值为零的字节或代码附加到每个多字节   由字符串文字或文字产生的字符序列。 78)多字节字符   然后,序列用于初始化静态存储持续时间和长度的数组   足以包含序列。对于字符串文字,数组元素具有   键入char,并使用多字节字符的各个字节进行初始化   序列。 [....]

内存分配仍然发生,只是未明确(通过内存分配器功能)。

也就是说,最后的"...\0"是重复的,如上所述(在引言的第一个语句中),默认情况下,数组将以null结尾。

答案 1 :(得分:2)

使用不带char的{​​{1}}变量表明您指定的字符串是只读的。这意味着您正在创建指向字符串常量的指针。 malloc位于内存的只读部分,你只是指向它。

现在,如果您想对字符串进行更改。我们假设将"hello world\0"更改为h,即H。如果没有str[0]='H'则无法制作。

答案 2 :(得分:1)

右。但在这种情况下,您只是指向一个放在常量内存区域中的字符串文字。您的指针在堆栈区域中创建。所以你只是指着另一个地址。即,在字符串文字的起始地址。

尝试使用复制指针变量中的字符串文字。然后它会给出错误,因为你没有分配内存。希望你现在明白。

答案 3 :(得分:1)

在C程序中声明字符串文字时,它存储在程序代码的read-only section中。 char *str = "hello";形式的语句将此字符串的地址分配给char*指针。但是,字符串本身(即字符hello以及\0字符串终结符)仍然位于只读存储器中,因此您根本无法更改它们。

请注意,您无需在字符串声明中显式添加零字节终结符。 C编译器会为你做这件事。

答案 4 :(得分:0)

字符串文字的存储在程序启动时保留并保持到程序退出。此存储可能是只读的,并且尝试修改字符串文字的内容会导致未定义的行为(它可能会起作用,它可能会崩溃,它可能会在它们之间执行某些操作)。