我想知道为什么不需要为字符串绑定内存就可以工作

I want to know why this works without having to bind memory for the string

大家好,我最近学习了 C 编程,但我一直停留在理解指针上。据我所知,要在指针中存储一个值,您必须将内存(使用 malloc)绑定到您要存储的值的大小。鉴于此,以下代码不应该工作,因为我没有分配 11 字节的内存来存储我的 11 字节大小的字符串,但由于某种超出我理解的原因,它工作得很好。

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

int main(){

  char *str = NULL;

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

在这种情况下

 str = "hello world[=10=]";

str指向chars数组首元素的地址,用"hello world[=13=]"初始化。也就是说,str指向一个"string literal".

根据定义,数组已分配,第一个元素的地址必须为"valid"。

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

In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals.78) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence. [....]

内存分配仍然发生,只是没有明确你(通过内存分配函数)。


就是说,末尾的 "...[=16=]" 是重复的,正如上面提到的(在引用的第一条语句中),默认情况下,数组将以 null 结尾。

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

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

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

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

使用不带 mallocchar 变量表明您分配的字符串是只读的。这意味着您正在创建一个指向字符串常量的指针。 "hello world[=12=]" 位于内存的只读部分中,您只是指向它。

现在,如果您想对字符串进行更改。假设将 h 更改为 H,即 str[0]='H'。没有 malloc 那是不可能的。

字符串文字的存储在程序启动时预留并一直保留到程序退出。此存储 可能 是只读的,并且尝试修改字符串文字的内容会导致未定义的行为(它可能会工作,可能会崩溃,可能会介于两者之间)。