我有点困惑为什么下面的爆炸:
char* c = "Hello World!";
*c = 'h';
当我在堆上分配字符串时,它会工作。所以我很好奇我最初的版本出了什么问题
char* c = "Hello World!";
是一个指向字符串字面值的指针,通常存储在只读内存段中。试图修改它是未定义的行为。像这样指向字符串字面值的指针应该更恰当地定义为
const char *c = "Hello World!";
,但const
经常被省略(至少在C语言中)。
你指向c
的字符串文字,最有可能存储在只读内存段,你不能改变它。即使你可以物理地改变它,按照C规范:
6.4.5(字符串字面值)
如果程序试图修改[字符串字面值],行为是未定义的。
如果您在堆(或堆栈)上分配内存,然后将字符串复制到该位置,您可以根据需要更改它。
char* c = "Hello World!";
这里c
是一个指针,它指向一个字面值字符串,所以你不能修改它
你可以用这个代替
char c[] = "Hello World!";
*c = 'h',
c
这里是一个char数组,包含字符串"Hello World!"
的字符,所以你可以修改它。
修改字符串文字是未定义的行为。这样做的主要原因是编译器允许将"Hello World!"
放在只读内存中。
另一方面,下面是可以的:
char c[] = "Hello World!";
*c = 'h';
像char * c = "Hello";
这样的字符串是字符串常量,存储在只读数据段中,所以你不能修改它们[但有些编译器允许]
堆分配的字符串不在只读段中,因此可以自由修改。