【问题标题】:How to auto increment the destination pointer with memcpy()?如何使用 memcpy() 自动增加目标指针?
【发布时间】:2021-12-26 22:22:59
【问题描述】:

基本上我需要做多个memcpy(),我不想在每次memcpy() 调用之后增加目标指针dst++;.. 只是想知道如何节省一些编码时间。

memcpy(dest, src1, 1); // uint8_t
dest += 1;
memcpy(dest, src2, 2); // uint16_t
dest += 2;
memcpy(dest, src3, 1024); // uint8_t*
dest += 1024;
...

如何做多个memcpy()为你增加目标指针?

【问题讨论】:

  • 例如 dest += 2;或 memcpy(dest + 1, src2, 2); ?
  • @VladfromMoscow 谢谢,没错,增加一行是一种解决方案。
  • static inline void *CopyAndUpdate(void * restrict s1, const void * restrict s2, size_t n) { return (char *) memcpy(s1, s2, n) + n; },然后是dest = CopyAndUpdate(dest, src1, 1); dest = CopyAndUpdate(dest, src1, 2);。或者static inline void CopyAndUpdate(char * restrict * s1, const void * restrict s2, size_t n) { memcpy(*s1, s2, n); *s1 += n; },然后CopyAndUpdate(&dest, src, 1); CopyAndUpdate(&dest, src, 2);,假设dest的类型是char *
  • @EugeneSh。没错,但这只是一个例子,我的真实数据最多为 1024 * 4 字节。
  • @EricPostpischil 谢谢埃里克,你的回答很完整。你的功能正是我所需要的。

标签: c pointers memcpy


【解决方案1】:

你可以做一个函数:

void memcpy_auto_inc( char **pp_dest, const void *src, size_t count )
{
    memcpy( *pp_dest, src, count );
    *pp_dest += count;
}

现在,假设dest 的类型是char*,而不是写

memcpy( dest, src1, 1 );
dest += 1;
memcpy( dest, src2, 2 );
dest += 2;
memcpy( dest, src3, 1024 );
dest += 1024;

你可以写:

memcpy_auto_inc( &dest, src1, 1 );
memcpy_auto_inc( &dest, src2, 2 );
memcpy_auto_inc( &dest, src3, 1024 );

但是,我怀疑这是否值得付出努力,因为它使代码不那么清晰并且不会为您节省大量输入,即使您为函数选择的名称比 memcpy_auto_inc 短得多。

编辑:

应 OP 的要求,我将提供有关 restrictinline 优化的更多信息:

函数memcpy_auto_inc可以通过改变函数原型使用restrict类型限定符来进一步优化:

void memcpy_auto_inc( char *restrict *restrict pp_dest, const void *restrict src, size_t count )

也可以添加inline 函数说明符。但是,在我看来,这不是必需的,因为这不太可能提高运行时性能。您通常可以依靠编译器的优化器来决定是否适合内联函数。

这个问题在这个问题中进一步讨论:

When to use inline function and when not to use it?

然而,这个问题已经存在 12 年了,并且编译器的优化器从那时起有了显着改进,所以现在使用 inline 关键字的理由更少了。

【讨论】:

  • 副作用是 C 魔鬼之一。当不是绝对需要时,应不惜一切代价避免。 memcpy(dest, src2, 2); dest+=2;memcpy_auto_inc( &dest, src2, 2); 好很多,因为很明显指针在这里被修改
  • @0__:我同意。但 OP 要求提供除 memcpy(dest, src2, 2); dest+=2; 以外的其他内容,以节省编码时间。
  • 但 IMO 这是最糟糕的选择。为什么 realloc 返回值而不是采用双指针。避免 SE
  • @AndreasWenzel,我们可以在您的memcpy_auto_inc() 中使用restrictinline 进行更多优化吗?
  • @ShellX3:我已经编辑了我的答案以解决您的评论。
【解决方案2】:

编写你自己的函数。

例如任何尺寸元素的通用:

void *generic(void *dest, const void *src, const size_t elemsize, size_t nelems)
{
    char *cptr = dest;

    memcpy(dest, src, elemsize * nelems);
    cptr += nelems * elemsize;
    return cptr;
}

或在您的示例中(字符大小元素)

void *charSizeOnly(void *dest, const void *src, size_t nelems)
{
    char *cptr = dest;

    memcpy(dest, src, nelems);
    cptr += nelems;
    return cptr;
}

示例用法:

    mytype *dest;
    mytype *src;
    /* ... some code*/
    /*it will copy and update the dest by 30 elements of type `mytype`*/
    dest = generic(dest, src, sizeof(*dest), 30); 

【讨论】:

    猜你喜欢
    • 2016-09-02
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多