Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
与memcpy连接_C_String_Memcpy - Fatal编程技术网

与memcpy连接

与memcpy连接,c,string,memcpy,C,String,Memcpy,我正在尝试使用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_cm

我正在尝试使用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++;
}
if(strlen(g->db\u cmd)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++;
}

您没有复制空终止符,您只是处理原始字符串数据。这会使字符串以非null结尾,这会导致各种问题。您也没有检查以确保缓冲区中有足够的空间,这可能会导致错误


要确保复制空终止符,只需在正在复制的字节数中添加1即可——复制
strlen(l->db.param_value.val)+1
字节。

一个可能的问题是第一个
memcpy()
调用不一定会导致以null结尾的字符串,因为您没有从
l->db.param_value.val
复制'\0'终止符:

因此,当在对
memcpy()
的第二次调用中调用
strlen(g->db_cmd)
时,它可能返回了完全虚假的内容。这是否是一个问题取决于
g->db\u cmd
缓冲区是否预先初始化为零

为什么不使用
strcat()
,它正是为了完成您想用
memcpy()执行的操作而设计的

如果
strlcat()
不是您平台的一部分,那么可以很容易地在网上找到它。如果您使用的是MSVC,则可以使用一个
strcat_s()
函数来代替它(但请注意,它并不等同于
strlcat()
——您必须更改调用
strcat_s()
的结果的检查和处理方式)

这将为您带来以下好处:

  • 减少对strlen的冗余调用。每个调用都必须遍历字符串,因此最好尽量减少这些调用
  • 第二个
    memcpy
    需要实际附加,而不是替换。因此,第一个参数必须与前一个调用不同
  • 注意第二个
    memcpy
    的第三个参数中的
    +1
    。那是给NUL终结者的
我不确定你的
if
声明是否有意义。也许更明智的做法是确保
g->db\u cmd
有足够的空间来复制您要复制的内容。您可以通过
sizeof
(如果
db\u cmd
是一个字符数组)或跟踪堆分配的大小(如果
db\u 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.
}
size\t param\u value\u len=strlen(l->db.param\u value.val),
del_const_len=strlen(l->del_const);
//假设db_cmd是一个字符数组,因此sizeof(db_cmd)是有意义的。
//如果db_cmd是一个堆分配,则将sizeof()替换为您需要的字节数
//向马洛克索要。
//
if(参数值+del_const_lendb_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);
}
其他的
{
//TODO:您的缓冲区不够大。请处理这个问题。
}

FYI:C允许将长语句拆分为多行,甚至可以拆分为多个带有额外变量的语句来保存中间结果。我要注意的是,一些嵌入式数据库(我认为berkeley DB)明确使用数据和长度。数据不需要以null结尾,并且可能包含null。在这种情况下,如果您的程序已经从DB API获得了长度,请保留该长度,并避免使用strlen。
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--;
}
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);
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.
}