strcat()函数的大小定义

时间:2014-01-04 14:56:25

标签: c string size strcat

问题是我为什么要定义字符串的大小(string[]应该是string[some-number]) 如果程序如下,它会给我Abort trap: 6

#include <stdio.h>
#include <string.h>

int main(void)
{
  char buffer1[] = "computer";
  char string[]="program";
  strcat( buffer1, string );
  printf( "buffer1 = %s\n", buffer1 );

}

这是来自http://www.tutorialspoint.com/cprogramming/c_data_types.htm的程序,它可以正常工作:

#include <stdio.h>
#include <string.h>

int main ()
{
   char str1[12] = "Hello";
   char str2[12] = "World";
   char str3[12];
   int  len ;

   /* copy str1 into str3 */
   strcpy(str3, str1);
   printf("strcpy( str3, str1) :  %s\n", str3 );

   /* concatenates str1 and str2 */
   strcat( str1, str2);
   printf("strcat( str1, str2):   %s\n", str1 );

   /* total lenghth of str1 after concatenation */
   len = strlen(str1);
   printf("strlen(str1) :  %d\n", len );

   return 0;
}

错误是什么?即使我在程序中定义了所有字符串大小,我的代码仍会提供Abort trap:6

4 个答案:

答案 0 :(得分:2)

来自strcat的手册页:

说明        strcat()函数将src字符串附加到dest字符串,覆盖termi-        在dest的末尾命名空字节('\ 0'),然后添加一个终止空字节。该        字符串可能不重叠, dest字符串必须有足够的空间用于结果。如果        dest不够大,程序行为不可预测;缓冲区溢出是一个        攻击安全程序的最佳途径。

当你声明你的字符串时,编译器会为buffer1(resp.string)分配初始字符串的大小为9(相应的8)(包括'\ 0')。

因此,strcat将导致9 - 1 + 8(即16个字节),但只有9个可用。

答案 1 :(得分:1)

strcat的第一个参数用于存储结果,因此它必须有足够的空间用于连接字符串。

在您的代码中:

char buffer1[] = "computer";

相当于:

char buffer1[9] = "computer";

定义一个char数组,其中只有足够的空间用于字符串"computer",但没有足够的空间用于结果。

答案 2 :(得分:1)

char buffer1[] = "computer";

创建一个足以容纳9个字符的缓冲区(strlen(1的“Hello”+ \0字节))。如果您再向其中写入数据,那么是未定义的行为(UB)。执行strcat时会发生这种情况 UB意味着程序可能会崩溃或显示任何行为。你很幸运,UB的程序因为不需要而崩溃,但是如果它至少有一个错误的迹象。大多数情况下,使用UB的程序将继续正常运行,并在您最不期望或想要它们时崩溃。

答案 3 :(得分:1)

您的strcat缓冲区溢出buffer1,只能容纳strlen("computer")+1个字节。省略数组大小并不意味着“动态”数组!当您指定数组的大小时,您可以根据需要保留多个字节:当然,您需要避免缓冲区溢出。

所以,

 strcpy(str3, str1);

 strcat( str1, str2);

是正常的,因为str3的{​​{1}}大小足够str1,而str1就足够strlen(str1) + strlen(str2) + 1,即恰好11:5(你好)+5(世界)+ 1(终结者)。选择了神奇的数字12是有原因的,大到足以容纳两个字符串和一个终结符。

关于C字符串

C字符串是字符数组,其中最后一个是“null”,'\0',即它们是字符数组,其中最后一个是0.这个终结符是必需的,以便字符串相关的函数可以理解字符串结束。

如果在字符串中间发现空字节,则从C字符串函数的角度来看,该字符串将在该点结束。 E.g。

char buffer1[] = "computer\0program";
// array: { 'c', 'o', ... '\0', 'p', 'r', 'o', .., 'm', '\0' }

// ...
printf("%s\n", buffer1);

仅打印computer。但此时缓冲区将足以容纳计算机和程序,一个终结符(和另一个额外的字节),因为编译器计算了char数组的大小,考虑到字符的字符序列,这些字符在语法上以第二个{{1}结束。 }}

但对于所有C字符串函数,"中包含的字符串为buffer1。另请注意,computer将给出正确的缓冲区大小,即17,与sizeof buffer1的结果相反,后者仅为8。