【问题标题】:c++ memcpy return valuec++ memcpy返回值
【发布时间】:2023-03-26 20:02:02
【问题描述】:

根据http://en.cppreference.com/w/cpp/string/byte/memcpy c++ 的memcpy 采用三个参数:目标、源和大小/字节。它还返回一个指针。为什么呢?参数不足以输入和复制数据。

还是我误解了什么?示例不使用返回值

【问题讨论】:

    标签: c++ memcpy


    【解决方案1】:

    通过返回一个值,可以将 memcpy 函数的调用用作右值。

    【讨论】:

    • 那为什么不简单地让它返回结果数组而不是作为参数传递呢?
    • “而不是将其作为参数传递”——请考虑几秒钟。
    • 因为你负责为目的地创建空间空间。 memcpy 不会创建任何新空间。
    • 因为 memcpy() 不会为目标分配新内存(即,它需要一个指向已分配内存的指针才能传递给它)。顺便说一句...我很少发现需要利用 memcpy() 的返回值。
    【解决方案2】:

    IIRC,在 C 的早期版本中,没有 void 返回。因此,由于遗留原因,已经存在足够长的库函数返回 something,这是他们能想到的最好的方法。

    string.h 中有一堆函数返回目标参数:memcpystrcpystrcat。它不是很有用,但它没有害处(可能在许多调用约定中甚至不需要指令来实现)。

    您可能会想出一个用法:char *nextbuf = memcpy(get_next_buf(), previous_buf+offset, previous_size-offset); 而不是 char *nextbuf = get_next_buf(); memcpy(nextbuf, etc); 或其他东西。

    为了比较,qsort 返回 void。它本可以根据“返回一些东西,它可能会派上用场”的原则定义为返回base,但事实并非如此。 std::copy 更有用地将迭代器返回到输出范围的 end。对于调用者计算的非随机访问迭代器可能不是微不足道的,甚至是不可能的。

    【讨论】:

      【解决方案3】:

      如果一个函数没有特定的返回值,通常习惯上返回一个输入参数(被视为主要参数的那个)。这样做允许您在表达式中使用“链式”函数调用。例如,你可以这样做

      char buffer[1024];
      strcat(strcpy(buffer, "Hello"), " World");
      

      特别是因为strcpy 返回原始dst 值作为其结果。基本上,在设计这样的函数时,您可能希望为“链接”选择最合适的参数并将其作为结果返回(同样,如果您注意到要返回的其他内容,即如果您的函数将返回 void)。

      有些人喜欢,有些人不喜欢。这是个人喜好的问题。 C 标准库通常支持这种技术,memcpy 是另一个例子。一个可能的用例可能类似于

      char *clone_buffer(const char *buffer, size_t size)
      {
         return memcpy(new char[size], buffer, size);
      }
      

      如果memcpy 没有返回目标缓冲区指针,我们可能不得不将上述实现为

      char *clone_buffer(const char *buffer, size_t size)
      {
         char *clone = new char[size];
         memcpy(clone, buffer, size);
         return clone;
      }
      

      看起来“更长”。这两种实现之间的效率没有任何差异。哪个版本更具可读性是有争议的。仍然有很多人可能会喜欢“免费”的机会来编写像上面第一个版本这样简洁的单行代码。

      人们常常对memcpy 返回目标缓冲区指针感到困惑,因为人们普遍认为从函数返回指针应该通常(或总是)表明该函数可能分配/重新分配内存。虽然这可能确实表示后者,但没有这样的硬性规则,而且从来没有,所以经常表达的观点认为返回指针(如memcpy确实)在某种程度上是“错误的”或“坏的”实践”是完全没有根据的。

      【讨论】:

      • 我想返回一些东西,而不是什么都不返回,在性能方面更昂贵,但是?
      • @hanshenrik:对于“重”返回值,它可能是真的,但对于标量返回值,效果要么不存在,要么可以忽略不计。标量值通常在 CPU 寄存器中返回,这意味着从某些低级别的角度来看,函数总是返回一些东西。从这个角度来看,您只需让它们返回有意义的值而不是无意义的值。即使对于“重”返回值,RVO 和 NRVO 也应该能够将惩罚降低到几乎为零。
      • @AnT, Even for "heavy" return values the RVO and NRVO should be able to reduce the penalty to virtually nothing. 在一个完美的世界里,他们“应该”。目前这种做法的真实性如何?
      • @cp.engr 现在编译器必须支持它:en.cppreference.com/w/cpp/language/copy_elision "返回值优化是强制性的,不再被视为复制省略"
      【解决方案4】:

      如果你想表明你没有使用它,你可以将 return 转换为 void - 例如:
      (void) memcpy(mydest, mysrc, mybytes);

      【讨论】:

        【解决方案5】:
        void *memcpy(void* dest, const void* src, std::size_t count);
        //returns void * which can be assigned to another void array that can be used as int or char data type.
        void *ret = new int[6];
        ret = memcpy(newarr, arr, sizeof(int)* 5);
        

        【讨论】:

        • 请解释你的答案。
        猜你喜欢
        • 1970-01-01
        • 2016-06-16
        • 1970-01-01
        • 2010-09-24
        • 2014-01-14
        • 2016-01-01
        • 2012-10-30
        • 2016-09-18
        • 2011-11-30
        相关资源
        最近更新 更多