Mav*_*ugu 4 c string strlen bus-error
我正在运行这个简单的程序,我得到的输出是"总线错误".使用一些调试语句我发现它发生的点是在strcat()调用.
#include<stdio.h>
#include<string.h>
main()
{
char *s = "this is ";
char *s1 = "me";  
strcat(s,s1); 
printf("%s",s);
return 0;
}
我在MAC,64位操作系统上使用gcc编译器运行它.如果我需要提供更多规格,请告诉我.
谢谢!
"this is "并且"me"是字符串文字,可以驻留在地址空间的只读部分.您不应该尝试修改这些.
char s[] = "this is ";
char s1[] = "me";  
这将确保将文字复制到堆栈 - 这是可写的.然后你的下面的strcat将溢出堆栈缓冲区,这同样糟糕.
以下内容将起作用 - 即使使用strcat而不是strncat一般的不良做法.
#include <stdio.h>
#include <string.h>
int main()
{
  char s[100] = "this is ";
  char *s1 = "me";  
  strcat(s,s1); 
  printf("%s",s);
  return 0;
}
一点背景:
表达"this is "和"me"是字符串常量 ; 它们分别是char  (const charC++中)的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
| 归档时间: | 
 | 
| 查看次数: | 5789 次 | 
| 最近记录: |