memcpy 与 startIndex ?

发布于 2024-07-28 23:37:44 字数 145 浏览 9 评论 0原文

我希望从一个特定的起点将特定长度的内容从一个缓冲区复制到另一个缓冲区。 我检查了 memcpy() ,但它只需要复制内容的长度,而我也想指定起始索引。

是否有任何函数可以执行此操作,或者是否有任何好的方法可以使用现有的 memcpy 函数来执行此操作?

I wish to copy content of specific length from one buffer to another from a specific starting point. I checked memcpy() but it takes only the length of content to be copied while I want to specify the starting index too.

Is there any function which can do this or is there any good approach to do it with the existing memcpy function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

温柔少女心 2024-08-04 23:37:44

我总是更喜欢语法

memcpy( &dst[dstIdx], &src[srcIdx], numElementsToCopy * sizeof( Element ) );

I always prefer the syntax

memcpy( &dst[dstIdx], &src[srcIdx], numElementsToCopy * sizeof( Element ) );
Spring初心 2024-08-04 23:37:44

只需将所需的偏移量添加到缓冲区的地址即可。

char abuff[100], bbuff[100];
....
memcpy( bbuff, abuff + 5, 10 );

这将从 abuff[5] 开始复制 10 个字节到 bbuff。

Just add the offset you want to the address of the buffer.

char abuff[100], bbuff[100];
....
memcpy( bbuff, abuff + 5, 10 );

This copies 10 bytes starting at abuff[5] to bbuff.

肥爪爪 2024-08-04 23:37:44

只需将偏移量添加到地址即可。 例如,如果您想复制从第 N 个字节开始的缓冲区:

memcpy( destination, source + N, sourceLen - N );

这将复制到目标。 如果您还想偏移目的地 - 将偏移量添加到两者:

memcpy( destination + N, source + N, sourceLen - N );

Just add the offset to the addresses. For example, if you wanted to copy the buffer starting with the Nth byte:

memcpy( destination, source + N, sourceLen - N );

This will copy to the destination. If you also want to offset the destination - add the offset to both:

memcpy( destination + N, source + N, sourceLen - N );
淑女气质 2024-08-04 23:37:44

不需要索引,因为您只需按指定的字节数更新源指针即可。 下面的包装应该可以解决问题

void* memcpy_index(void *s1, const void *s2, size_t index, size_t n) {
  s2 = ((char*)s2)+index;
  return memcpy(s1, s2,n);
}

An index is not required because you can simply update the source pointer by the specified number of bytes. The following wrapper should do the trick

void* memcpy_index(void *s1, const void *s2, size_t index, size_t n) {
  s2 = ((char*)s2)+index;
  return memcpy(s1, s2,n);
}
我不咬妳我踢妳 2024-08-04 23:37:44

只需将指针增加到起始索引即可。

示例

const unsigned char * src = reinterpret_cast<const unsigned char*>(your source);
unsigned char * dest = reinterpret_cast<unsigned char *>(your dest);
memcpy(dest, src + offset, len);

使用 STL 集合来避免内存访问错误怎么样?

Simply increase your pointer to your start index.

Example

const unsigned char * src = reinterpret_cast<const unsigned char*>(your source);
unsigned char * dest = reinterpret_cast<unsigned char *>(your dest);
memcpy(dest, src + offset, len);

What about using STL collections to avoid memory access errors?

走野 2024-08-04 23:37:44

除了匿名回答之外,该网站还需要一种允许匿名跟进的方法。

为什么我不止一次看到这种疯狂的断言:“索引”必须以 1 字节为单位? 这与惯例完全相反。 “索引”通常是象征性的,其物理字节偏移量由数组(或向量,甚至可能没有数组的物理布局,但随后 memcpy() 也无关)中元素的大小确定课程)。

因此,数组中的第 5 个元素的“索引”为 5,但是:

  • 如果数组为 char 类型,则该“索引”的字节偏移量为 5。
  • 如果数组为 Short 类型(在 x86 上),则该字节偏移量该“索引”的值为 10。
  • 如果该数组为 int 类型(在 x86 上),则该“索引”的字节偏移量为 20。
  • 如果该数组是某个大型 48 字节对象的类型,则该数组的字节偏移量为“index”是240。

哪种方式是访问该特定元素的正确方式是一个侧面。 重要的是您了解其中的差异,选择一个,并使代码正确。


关于单词的含义,我宁愿阅读:

 void* memcpy_offset(void *s1, const void *s2, size_t offset, size_t n);

而不是:

 void* memcpy_index(void *s1, const void *s2, size_t index, size_t n);

我发现完全通用的 void * 可能有“索引”的想法具有误导性。 (当我们在这里时,“dest”和“source”或“in”和“out”将比“s1”和“s2”更明确。当您选择不言自明时,代码不需要那么多注释变量名。)

This site needs a way to allow anonymous followups in addition to anonymous answers.

Why, more than once, do I see this insane assertion that an "index" must be in units of 1 byte? It's the complete opposite of convention. An "index" is usually symbolic, a measure whose physical byte offset is determined by the size of the element in the array (or vector, which may not even have the physical layout of an array, but then memcpy() is irrelevant too of course).

So, the 5th element in an array has "index" 5, but:

  • If the array is type char, then the byte offset of that "index" is 5.
  • If the array is type short (on x86), then the byte offset of that "index" is 10.
  • If the array is type int (on x86), then the byte offset of that "index" is 20.
  • If the array is type of some large 48-byte object, then the byte offset of that "index" is 240.

Which way is the correct way to access that specific element is a side point. The important part is that you understand the difference, choose one, and make the code correct.


On the meaning of words, I would much rather read:

 void* memcpy_offset(void *s1, const void *s2, size_t offset, size_t n);

than:

 void* memcpy_index(void *s1, const void *s2, size_t index, size_t n);

I find the idea that a completely generic void * could have an "index" to be misleading. (While we're here, "dest" and "source" or "in" and "out" would be much less ambiguous than "s1" and "s2". Code doesn't need as many comments when you pick self-explanatory variable names.)

寒尘 2024-08-04 23:37:44

只需将索引添加到缓冲区的地址,并将其作为源参数传递给 memcpy() ,例如从缓冲区 b 的第 3 个项目复制

char a[10], b[20];
::memcpy(a,b+2,10);

还要考虑缓冲区中项目的类型, memcpy() 的长度(第三个)参数以字节为单位,因此要复制 4 个整数,您应输入 4*sizeof(int) - 这可能是 16(在 32 位系统上)。但类型对于起始地址并不重要,由于指针算术:

int a[10], b[10];
::memcpy( a+2, b, 2*sizeof(int) );
// a+2 will be address of 3rd item in buffer a
// not address of 1st item + 2 bytes

Simply add the index to the address of the buffer, and pass it to memcpy() as the source parameter, e.g. copy from 3rd item of buffer b

char a[10], b[20];
::memcpy(a,b+2,10);

Also take into account the type of items in the buffer, length (3rd) parameter of memcpy() is in bytes, so to copy 4 ints you shall put 4*sizeof(int) - which will probably be 16 (on a 32 bit system. But the type does not matter for the start address, because of pointer arithmetics:

int a[10], b[10];
::memcpy( a+2, b, 2*sizeof(int) );
// a+2 will be address of 3rd item in buffer a
// not address of 1st item + 2 bytes
绿光 2024-08-04 23:37:44

你可以有一个像下面这样的函数。

template<typename T>
T* memcopy_index(T* dst,T* src,unsigned int index, unsigned int element_count)
{
    return (T*)memcpy(dst,src + index, element_count * sizeof(T));
}

它可以如下使用:

int src[]={0,1,2,3,4,5,6};
int dst[15];

memcopy_index(dst,src,2,5);    //copy 5 elements from index 2

您必须确保目标缓冲区有足够的空间来复制元素。

You could have a function like below.

template<typename T>
T* memcopy_index(T* dst,T* src,unsigned int index, unsigned int element_count)
{
    return (T*)memcpy(dst,src + index, element_count * sizeof(T));
}

It can be used as below:

int src[]={0,1,2,3,4,5,6};
int dst[15];

memcopy_index(dst,src,2,5);    //copy 5 elements from index 2

You have to make sure that destination buffer has enough room to copy the elements.

撑一把青伞 2024-08-04 23:37:44

如果您使用 C++,最好使用 std::copy() 而不是 memcpy()。 std::copy 可以像迭代器一样轻松地获取指针。

例如,

int src[20];
int dst[15];

// Copy last 10 elements of src[] to first 10 elements of dst[]
std::copy( src+10, src+20, dst );

与 memcpy() 一样,您有责任确保指针有效。

笔记。 如果您的使用对性能至关重要,您可能会更快地找到其他答案中详细介绍的 memcpy() ,但可能不会太多。

If you're using c++, it is probably better to use std::copy() instead of memcpy(). std::copy can take pointers just as easily as iterators.

e.g.

int src[20];
int dst[15];

// Copy last 10 elements of src[] to first 10 elements of dst[]
std::copy( src+10, src+20, dst );

As with memcpy(), it's your responsibility to make sure the pointers are valid.

NOTE. If your usage is performance critical you may find a memcpy() as detailed in the other answers quicker, but probably not by much.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文