大家好,我最近选择了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;
}
答案 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*
指针。但是,字符串本身(即字符h
,e
,l
,l
和o
以及\0
字符串终结符)仍然位于只读存储器中,因此您根本无法更改它们。
请注意,您无需在字符串声明中显式添加零字节终结符。 C编译器会为你做这件事。
答案 4 :(得分:0)
字符串文字的存储在程序启动时保留并保持到程序退出。此存储可能是只读的,并且尝试修改字符串文字的内容会导致未定义的行为(它可能会起作用,它可能会崩溃,它可能会在它们之间执行某些操作)。