One possible problem is that your first memcpy()
call won't necessarily result in a null terminated string since you're not copying the '\0' terminator from l->db.param_value.val
:
So when strlen(g->db_cmd)
is called in the second call to memcpy()
it might be returning something completely bogus. Whether this is a problem depends on whether the g->db_cmd
buffer is initialized to zeros beforehand or not.
Why not use the strcat()
, which was made to do exactly what you're trying to do with 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++;
}
That'll have the advantage of being easier for someone to read. You might think it would be less performant - but I don't think so since you're making a bunch of strlen()
calls explicitly. In any case, I'd concentrate on getting it right first, then worry about performance. Incorrect code is as unoptimized as you can get - get it right before getting it fast. In fact, my next step wouldn't be to improve the code performance-wise, it would be to improve the code to be less likely to have a buffer overrun (I'd probably switch to using something like strlcat()
instead of strcat()
).
For example, if g->db_cmd
is a char array (and not a pointer), the result might look like:
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--;
}
If strlcat()
isn't part of your platform it can be found on the net pretty easily. If you're using MSVC there's a strcat_s()
function which you could use instead (but note that it's not equivalent to strlcat()
- you'd have to change how the results from calling strcat_s()
are checked and handled).