#include <string.h> - &gt;中止陷阱:6?

时间:2018-02-16 05:43:42

标签: c include string.h

我在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
$

2 个答案:

答案 0 :(得分:3)

strcat尝试附加字符,但是数组的大小又不足以让它们给你undefined behavior。(在这种情况下,未定义的行为导致你看到的错误 - 它可能是一切都有效的情况。)因为strcat试图超越数组aprintf的第一个参数应该是格式说明符,如printf("%s",a);

char a[] = {'H','e','y','a','\0'};

此处a有5个元素。数组的大小为5。你需要采取更大的阵列。

char a[9] = {'H','e','y','a','\0'};

如果你让数组保持9个字符,那就可以了。

答案 1 :(得分:3)

初始化数组并省略维度时,编译器会根据初始化程序的数量推断维度 所以,这句话:

char a[] = {'H','e','y','a','\0'};

相当于:

char a[5] = {'H','e','y','a','\0'};

strcat()将源字符串的副本附加到目标字符串。它不检查目标缓冲区是否足够大以包含连接的结果字符串。如果目标不足以容纳连接的结果字符串,那么它会导致未定义的行为,包括它可能执行不正确(崩溃或静默生成不正确的结果),或者它可能完全符合程序员的意图。

您应该指定缓冲区a的大小足以容纳连接的结果字符串。在您的计划中,源字符串bro!的大小为4strcat()使用源字符串的第一个字符覆盖目标null字符,同时连接它们,并且在形成的新字符串的末尾包含空字符。因此,在您的情况下,保持连接结果字符串所需的最小大小为9

a声明为:

char a[9] = {'H','e','y','a','\0'};

应该可以正常工作。

正如David建议(在评论中)而不是9,您可以采用一些合理大小的缓冲区,例如5121024(例如a[512]或{{1 }})。 它可以帮助您在一定程度上避免问题。但是,您需要处理代码中的缓冲区溢出问题。例如,您可以使用strncat(),这样您就可以灵活地指定可以在目标字符串中追加的最大尺寸。
您可以指定要附加的最大字符数 -

a[1024]

以避免缓冲区溢出。