strncpy运行时检查失败#2错误c ++

时间:2012-09-01 02:11:54

标签: c++ runtime

当我编译并运行我的程序时,似乎一切正常,除了我得到“运行时检查失败#2”错误之外的任务。顺便说一句,这是我的hw任务,这是我第一次尝试使用任何cstring函数,所以我确定这是我出错的地方。基本上我将2个字符串附加在一起,我几乎100%确定它与我的结果参数溢出有关。只是不知道如何解决它。

#include <iostream>
#include <cstring>
using namespace std;

void concat(const char a[ ], const char b[ ], char result[ ], int result_maxlength);
int main()
{
  char a[] = "Woozle";
  char b[] = "Heffalump";
  char c[5];
  char d[10];
  char e[20];
  concat(a, b, c, 5);
  concat(a, b, d, 10);
  concat(a, b, e, 20);
  cout << c << "\n";
  cout << d << "\n";
  cout << e << "\n";
  return 0;
}
void concat(const char a[ ], const char b[ ], char result[ ], int result_maxlength)
{
strncpy (result,a, result_maxlength);
strncat (result, b, result_maxlength);
result[result_maxlength-1] = '\0';
}

2 个答案:

答案 0 :(得分:1)

strncat非常没用,因为num参数不是目标的总大小,而是要复制的字节数。

答案 1 :(得分:1)

到目前为止,有几个问题指出了这个代码。一个非常微妙的,似乎很少谈论的是:根据POSIX规范,如果移动的非空字符数达到指定的限制,strncpy的行为将不会在字符串上设置空终止符(然后')。但是,它会尾部填充空值以达到'n'。因此:

char ar[3];
strncpy(ar, "food", sizeof(ar)/sizeof(ar[0]));

这将以(0)='f',a(1)='o'和ar(2)='o'结束。 不会附加空终止符。忽略最后一个字符由于这个原因,人们对于调用这个运行时库函数是如此负面。考虑到这一点很重要。因此,您经常会看到这样的代码。

char ar[3];
strncpy(ar, "food", sizeof(ar)/sizeof(ar[0])-1);
ar[sizeof(ar)/sizeof(ar[0])-1] = 0;

这可能会得到你真正想要的东西,即ar =“fo”。充足的空间情况扭转了这一局面。如果你有一个有足够空间的缓冲区,'n'将使用空值进行尾部填充,直到达到'n',如果副本的源字符串在到达'n'之前到达它自己的终结符。因此:

char ar[30];
strncpy(ar, "food", sizeof(ar)/sizeof(ar[0])-1);
ar[sizeof(ar)/sizeof(ar[0])-1] = 0;

在'd'之后将导致ar =“food”,其中有26个零字符。保持人们的脚趾,不那么明显的memset-to-zero调用:

char ar[30];
strncpy(ar, "", sizeof(ar)/sizeof(ar[0]));

是的,这是错的,我知道。

所有这一切都说明了strncat()的行为与您的代码似乎反映出来的情况不同也就不足为奇了。例如,最后一个参数未指定要在目标中限制的字符数。相反,它描述了从源复制限制的字符数。换句话说,当你继续使用新的字符串时,尾部空间限制器应该不断变短。当然,要知道多少涉及跟踪每个步骤复制的字符,并且正如有人指出的那样,这使得strncat在许多情况下无边界无用,提供了比实用程序更多的混乱。

作为参考,可以在此处strncpystrncat查看具有已定义行为的精确定义。在继续做作业之前,我强烈建议您仔细阅读这两本书。

相关问题