我正在尝试使用memcpy将两个字符串添加到一起。我需要,第一个memcpy确实包含数据。然而,第二个没有添加。知道为什么吗?
if (strlen(g->db_cmd) < MAX_DB_CMDS )
{
memcpy(&g->db_cmd[strlen(g->db_cmd)],l->db.param_value.val,strlen(l->db.param_value.val));
memcpy(&g->db_cmd[strlen(g->db_cmd)],l->del_const,strlen(l->del_const));
g->cmd_ctr++;
}发布于 2011-08-04 02:28:05
size_t len = strlen(l->db.param_value.val);
memcpy(g->db_cmd, l->db.param_value.val, len);
memcpy(g->db_cmd + len, l->del_const, strlen(l->del_cost)+1);这将为您带来以下好处:
减少对strlen的
memcpy实际上需要追加,而不是替换。所以第一个参数必须不同于之前的调用,注意第二个memcpy的第三个参数中的+1。这是给NUL终结者的。我也不确定您的if语句是否有意义。也许更明智的做法是确保g->db_cmd有足够的空间来存储您将要复制的内容。您可以通过sizeof (如果db_cmd是一个字符数组)或通过跟踪堆分配的大小(如果db_cmd是通过malloc获得的)来实现。因此,也许它最有意义的原因是:
size_t param_value_len = strlen(l->db.param_value.val),
del_const_len = strlen(l->del_const);
// Assumption is that db_cmd is a char array and hence sizeof(db_cmd) makes sense.
// If db_cmd is a heap allocation, replace the sizeof() with how many bytes you
// asked malloc for.
//
if (param_value_len + del_const_len < sizeof(g->db_cmd))
{
memcpy(g->db_cmd, l->db.param_value.val, param_value_len);
memcpy(g->db_cmd + param_value_len, l->del_const, del_const_len + 1);
}
else
{
// TODO: your buffer is not big enough. handle that.
}发布于 2011-08-04 02:24:28
您不是在复制null终止符,您只是在复制原始字符串数据。这使得您的字符串不能以null结尾,这可能会导致各种问题。您也没有检查以确保缓冲区中有足够的空间,这可能会导致buffer overflow vulnerabilities。
为了确保复制空终止符,只需在要复制的字节数上加1 --复制strlen(l->db.param_value.val) + 1字节。
发布于 2011-08-04 02:26:02
一个可能的问题是,由于您没有从l->db.param_value.val复制'\0‘终止符,所以第一个memcpy()调用不一定会导致以null结尾的字符串
因此,当在第二次调用memcpy()时调用strlen(g->db_cmd)时,它可能会返回一些完全虚假的东西。这是否是一个问题取决于是否事先将g->db_cmd缓冲区初始化为零。
为什么不使用strcat(),它就是用来做您想要用memcpy()做的事情的
if (strlen(g->db_cmd) < MAX_DB_CMDS )
{
strcat( g->db_cmd, l->db.param_value.val);
strcat( g->db_cmd, l->del_const);
g->cmd_ctr++;
}这样做的好处是让人更容易阅读。您可能认为它的性能会较差--但我不这么认为,因为您显式地执行了一堆strlen()调用。在任何情况下,我都会专注于先做好它,然后再担心性能。不正确的代码是未优化的--在快速获得它之前,先得到它。实际上,我的下一步不是改进代码的性能,而是改进代码以减少缓冲区溢出的可能性(我可能会改用strlcat()而不是strcat())。
例如,如果g->db_cmd是一个字符数组(而不是指针),则结果可能如下所示:
size_t orig_len = strlen(g->db_cmd);
size_t result = strlcat( g->db_cmd, l->db.param_value.val, sizeof(g->db_cmd));
result = strlcat( g->db_cmd, l->del_const, sizeof(g->db_cmd));
g->cmd_ctr++;
if (result >= sizeof(g->db_cmd)) {
// the new stuff didn't fit, 'roll back' to what we started with
g->db_cmd[orig_len] = '\0';
g->cmd_ctr--;
}如果strlcat()不是你的平台的一部分,你可以很容易地在网上找到它。如果你使用的是MSVC,你可以使用一个strcat_s()函数来代替(但请注意,它不等同于strlcat() -你必须改变检查和处理调用strcat_s()的结果的方式)。
https://stackoverflow.com/questions/6931193
复制相似问题