【发布时间】:2018-02-16 05:43:41
【问题描述】:
我正在学习 c 编程,但遇到了一些奇怪的事情。
我在搞乱 char 数组/字符串并使用不同的函数。所以我有了这个程序,
#include <stdio.h>
int main(){
char a[] = {'H','e','y','a','\0'};
strcat(a,"bro!");
printf(a);
}
$ gcc -o test.o test.c -Wall
$ ./test.o
Heya bro!
$
按预期工作,但如果我添加
#include <string.h>
一开始,我就明白了
$ gcc -o test.o test.c -Wall
$ ./test.o
Abort: trap 6
$
【问题讨论】:
-
使用
.o扩展名调用您的可执行文件是一种惯例;用于目标文件,通常不是完整的程序。您的原始代码无法在 C99 或 C11 规则下干净地编译。您的strcat()调用调用未定义的行为;你写超出了你的数组的末尾。使用 UB,任何事情都是允许的——崩溃、看起来可以工作、重新格式化您的硬盘。 -
未定义的行为,你在
char a[]后面吹了,你不幸第一次得到了你想要的结果。使a足够大以适合串联的字符串数组。 -
我对这两种不同的行为感到惊讶(我知道 UB 就是 UB),但大多数时候事情是确定性的。如果不包含
string.h,编译器会发出对strcat的调用。但是,如果您包含标头,则可能会发生这种情况,这里就是这种情况,发出的调用不是普通的strcat。在我的机器上,它调用__strcat_chk,它的行为不同并产生中止。