为什么这个编译没有错误?

时间:2014-04-27 00:02:21

标签: c strcpy

我是C的一个完整的菜鸟,我需要一些帮助来理解为什么某段代码能够正确编译。

main(){
    char name[3];
    strcpy(name, "12345678912312");
    printf("%s\n",name);
}

因此,此代码正确编译;但是,我不明白为什么它不会导致分段错误。根据我对c的理解,每个字符都是1个字节。数组名称应该能够容纳3个字节,而不是它可以容纳更多。那是为什么?

此外,如果我再添加一个字符,我将收到非法指令(核心转储)。

main(){
    char name[3];
    strcpy(name, "123456789123121");
    printf("%s\n",name);
}

然后,如果我向该代码添加另一个字符,它将抛出Segmentation fault(core dumped)错误。为什么错误不同?为什么他们之前没有出现?

最后,我在哪里可以找到每个功能的文档?我来自java,所以我习惯引用java文档。

我在Ubuntu linux中使用GCC编译器。

2 个答案:

答案 0 :(得分:1)

两个代码都会调用未定义的行为,因为您正在写入未分配的内存位置。在这种情况下,一切都可能发生您的程序运行,可能会或可能不会给出预期的输出,否则会崩溃或给出分段错误 另请注意,strcpy不检查数组绑定,编译器不会为其引发任何警告/错误。

答案 1 :(得分:1)

如果您在此处阅读了几个问题,您会听到很多关于"未定义的行为",通常缩写为UB。

这意味着如果你的程序在C标准之外做了某些事情,标准就不会定义会发生什么。任何事情都可能发生。

写一个数组的末尾是一个可以触发UB的例子。

C不进行数组绑定检查,因此如果您尝试在数组末尾写入,结果将取决于编译器如何实现数组,它们如何在内存中排列,以及它们之后的内容。然而,关键是你不能依赖任何特定的行为。

我最喜欢的C和C ++参考站点是cppreference。但是在Linux上你也可以用man来阅读库函数的定义,例如。 man strcpy