覆盖c字符串时发生访问冲突

Access violation when overwriting c string

本文关键字:访问冲突 字符串 覆盖      更新时间:2023-10-16

我有点困惑为什么下面的爆炸:

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";这样的字符串是字符串常量,存储在只读数据段中,所以你不能修改它们[但有些编译器允许]

堆分配的字符串不在只读段中,因此可以自由修改。