strcpy()的分段错误

这有效:

int main() { char *t = "Hello"; t = "World"; printf("%s", t); } 

但是这给出了分段错误:

 int main() { char *t = "Hello"; strcpy(t, "World"); // the only difference printf("%s", t); } 

为什么?

您明确定义的字符串 – 例如"Hello" – 通常放在只读存储器的区域中。 这些字符串无法更改。

在第一个示例中,您没有将“Hello”字符串更改为“World”字符串。 您正在重新分配t ,使其指向 “World”而不是“Hello”。 “Hello”字符串仍然在未读取的内存中闲置。

这是初始状态:

 t -> "Hello" "World" 

这是第二个状态:

  "Hello" t -> "World" 

在第二个示例中,您尝试覆盖“Hello”字符串。 这是不可能做到的。

您应该将声明从char *t更改为const char *t 。 我认为GCC可以配置为强制执行此操作。

第一个将t的值更改为从"Hello"的地址指向"World"的地址。 第二次尝试覆盖数据"Hello"本身。

在第一个例子中,指针t指向一个字符串常量"Hello" ,然后立即指向字符串常量"World" ; 然后打印后一个值。

第二个示例中的代码与segfault崩溃,因为字符串常量不可写。 (strcpy尝试修改包含文本"Hello"的内存)。 除非使用-fwriteable-strings编译,否则GCC会将字符串常量放入只读部分。

代码

 char *test = "Hello"; 

表示编译器+链接器在只读部分中放置一串字节“Hello \ 0”, test指向其第一个字符。 任何通过此指针写入的尝试都会受到操作系统的严厉惩罚。

另一方面

 char test[] = "Hello"; 

声明一个包含6个字符的数组,初始值为( { 'H', 'e', 'l', 'l', 'o', '\0' } )。

一些旧程序假设字符串常量是可写的; 因此要求GCC支持使用-fwriteable-strings命令行开关编译这些程序。

赋值t = "World"仅更改指针,而strcpy更改t指向的内存。 字符串文字可能位于只读段中。

char* t是一个指针。 在第一个示例中,您只是将指针从一个字符串文字指定给另一个字符串:首先指向"Hello" ,然后指向"World" 。 这完全合法。

但是,字符串文字本身就是文字 – 它们无法更改。 通常它们位于内存的只读部分。 在第二个示例中,您尝试通过用"World"覆盖它来更改分配给字符串文字"Hello"的内存中的内容。 这是非法的,你会得到一个分段错误。

char *t="Hello" Hello”中,在只读位置分配“Hello”。 因此,写入只读位置会导致分段错误。

分配和复制之间有区别。

您尝试将另一个字符串的地址分配给t第一个示例。

在第二个示例中,您尝试写入只读位置。

使用char t[] = "Hello" 。 这里可以覆盖

更多解释在这里

“Hello”是一个字符串常量。 它并不意味着通过常量的定义来写。

在你的第一个例子中,’t’是一个指针,它可以指向(被赋值)字符串常量。