strcpy()的分段错误

时间:2013-08-22 19:03:30

标签: c 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);
}

为什么?

7 个答案:

答案 0 :(得分:4)

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

在第一个示例中,您没有将“Hello”字符串更改为“World”字符串。您正在重新分配t,以便指向到“World”而不是“Hello”。 “Hello”字符串仍在闲置,只读存储器中。

这是初始状态:

t -> "Hello"
     "World"

这是第二个州:

     "Hello"
t -> "World"

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

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

答案 1 :(得分:3)

在第一个例子中,指针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命令行开关来编译这些程序。

答案 2 :(得分:3)

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

答案 3 :(得分:2)

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

分配和复制之间存在差异。

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

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

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

更多解释Here

答案 4 :(得分:2)

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

答案 5 :(得分:2)

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

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

答案 6 :(得分:1)

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

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