我可以调用memcpy()和memmove()并将"字节数"设置为零吗?

sha*_*oth 91 c c++ pointers memcpy memmove

当我无法移动/复制memmove()/ memcpy()作为边缘情况时,我是否需要处理案例

int numberOfBytes = ...
if( numberOfBytes != 0 ) {
    memmove( dest, source, numberOfBytes );
}
Run Code Online (Sandbox Code Playgroud)

或者我应该在没有检查的情况下调用该函数

int numberOfBytes = ...
memmove( dest, source, numberOfBytes );
Run Code Online (Sandbox Code Playgroud)

是否需要检查前片段?

Mik*_*our 131

从C99标准(7.21.1/2):

声明为的参数size_t n指定函数数组的长度,在n调用该函数时可以为零.除非在本子条款中对特定函数的描述中另有明确说明,否则此类调用上的指针参数仍应具有有效值,如7.1.4中所述.在这样的调用中,定位字符的函数不会发生,比较两个字符序列的函数返回零,复制字符的函数复制零个字符.

所以答案是否定的; 检查是没有必要的(或者是;你可以传递零).

  • @neverhoodboy:不,引用清楚地说"`n`的值可以为零".你是不对的,你不能传递空指针,但这不是问题所在. (6认同)
  • 如果指针指向数组最后一个元素后面的位置,那么对于此类函数而言,该指针是否会被视为“有效”?这样的指针无法被合法地引用,但是可以安全地执行其他一些类似指针的操作,例如从中减去一。 (3认同)
  • @MikeSeymour:我的错。真对不起。问题是关于大小而不是指针。 (3认同)

Mat*_*lia 5

正如@You所说,该标准指定memcpy和memmove应该可以毫无问题地处理这种情况。因为它们通常以某种方式实现

void *memcpy(void *_dst, const void *_src, size_t len)
{
    unsigned char *dst = _dst;
    const unsigned char *src = _src;
    while(len-- > 0)
        *dst++ = *src++;
    return _dst;
}
Run Code Online (Sandbox Code Playgroud)

除了函数调用之外,您甚至不应有任何性能损失;如果编译器支持此类函数的内在函数/内联,则额外的检查甚至可能使代码的速度稍慢一些,因为该检查已经在同一时间完成了。

  • -1,典型的实现与用零参数调用这些函数(甚至可能没有实现为C函数)是否有效C无关。 (9认同)
  • 正如我在回答之初所说的那样,其他答案已经涵盖了它是有效的C的事实:“正如@You所说,_thestandard_指定memcpy和memmove应该毫无问题地处理这种情况”。我只是基于这样的事实添加了我的观点:出于性能原因,您甚至不必担心用len = 0调用memcpy,因为在这种情况下,这几乎是零成本。 (4认同)