c语言bus+error,运行简单的字符串C程序时出现总线错误

本问题已经有最佳答案,请猛点这里访问。

我正在运行这个简单的程序,我得到的输出是"总线错误"。 使用一些调试语句,我发现它发生在strcat()调用处。

#include

#include

main()

{

char *s ="this is";

char *s1 ="me";

strcat(s,s1);

printf("%s",s);

return 0;

}

我在Mac 64位OS上使用gcc编译器运行它。 请让我知道是否需要提供更多规格。

谢谢!

"this is"和"me"是字符串文字,可以驻留在地址空间的只读部分中。您不应尝试修改它们。

char s[] ="this is";

char s1[] ="me";

这将确保将文字复制到堆栈中-这是可写的。然后,您后面的strcat将溢出堆栈缓冲区,这同样很糟糕。

以下内容将起作用-即使通常不使用strcat而不是strncat。

#include

#include

int main()

{

char s[100] ="this is";

char *s1 ="me";

strcat(s,s1);

printf("%s",s);

return 0;

}

对于不知道如何正确使用它的人来说,strcat只是不好的做法。这些人应该坚持使用BASIC :-)但是+1,因为您已将其钉牢。

@paxdiablo:是的,因此"一般";)

哇,让我记得很久以前发生在我身上的一个讨厌的错误。我遇到了段错误,然后才意识到这很困难。

当程序变得复杂时,要跟踪字符串的大小确实非常困难。感谢您指出警告。.请注意!

一点背景:

表达式"this is"和"me"是字符串文字;它们分别是具有静态范围的char(在C ++中为const char)的9元素数组和3元素数组(这意味着它们的内存在程序启动时分配并保持到程序退出)。该内存可能是可写的,也可能是不可写的,具体取决于平台,因此尝试修改字符串文字会导致未定义的行为(这意味着编译器实际上可以执行其想要执行的任何操作)。简而言之,您无法写入字符串文字。

编写strcat(s, s1);时,遇到两个问题:首先,目标数组是字符串文字,正如我上面提到的那样,它不可写。其次,它的大小不足以容纳其他字符。它的大小可以容纳9个字符(包括0终止符),但是您正尝试在其中存储11个字符。这是缓冲区溢出,如果您破坏了一些重要内容,则可能导致不良后果。

您必须分配一个可写的目标缓冲区。您有几种选择:

您可以声明一个足够大以容纳结果字符串的数组,尽管通常您不会在编译时知道"足够大"的大小:

char *s ="this is";

char *s1 ="me";

char target[11];

strcpy(target, s);

strcat(target, s1);

// alternately, sprintf(target,"%s%s", s, s1);

在C99中,您可以声明一个可变长度数组(VLA),其大小在运行时之前是未知的:

char *s ="this is";

char *s1 ="me";

char target[strlen(s) + strlen(s1) + 1];

strcpy(target, s);

strcat(target, s1);

// alternately, sprintf(target,"%s%s", s, s1);

您可以使用malloc或calloc动态分配目标缓冲区(这实际上是首选方法,因为可以根据需要调整缓冲区的大小,这与VLA不同):

char *s ="this is";

char *s1 ="me";

char *target = malloc(strlen(s) + strlen(s1) + 1);

strcpy(target, s);

strcat(target, s1);

// or sprintf(target,"%s%s", s, s1);

...

free(target); // when you're finished with the buffer

执行该操作的各种可能性值得关注。谢谢!

"静态程度"? -我认为您要查找的短语是"静态存储期限"。除此之外,一个很好的答案。

您需要阅读更多有关字符串如何在C中工作以及字符数组和字符串文字之间的区别的更多信息。

为此,请按如下所示对其进行重写:

#include

#include

#include

int main(void)

{

char s[100] ="this is";

char *s1 ="me";

strcat(s, s1);

printf("%s", s);

return EXIT_SUCCESS;

}

还有几点:

main()返回int。

符号EXIT_SUCCESS(来自的符号清零)。

在C中,不带参数的函数应声明为void。对于main(),空括号无效。

我发现EXIT_SUCCESS不会比零更清晰;它只是混乱。像FALSE这样的宏也是如此。

感谢您的详细说明。我想我应该开始采用一种更正式的编程风格。但是我无法理解EXIT_SUCCESS如何为更好的调试过程提供帮助?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值