C++ memcpy 与 startIndex?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1163624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:04:43  来源:igfitidea点击:

memcpy with startIndex?

c++memcpy

提问by Goz

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.

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

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

是否有任何功能可以做到这一点,或者有什么好的方法可以用现有的memcpy功能做到这一点?

回答by Goz

I always prefer the syntax

我总是喜欢语法

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

回答by Goz

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.

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

回答by sharptooth

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

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

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:

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

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

回答by JaredPar

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);
}

回答by Edouard A.

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?

如何使用 STL 集合来避免内存访问错误?

回答by Matthew

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).

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

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

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

  • 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.
  • 如果数组是 char 类型,则该“索引”的字节偏移量为 5。
  • 如果数组是 short 类型(在 x86 上),则该“索引”的字节偏移量为 10。
  • 如果数组是 int 类型(在 x86 上),则该“索引”的字节偏移量为 20。
  • 如果数组是某个大型 48 字节对象的类型,则该“索引”的字节偏移量为 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.)

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

回答by CsTamas

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

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

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:

还要考虑缓冲区中项目的类型,memcpy() 的长度(第 3 个)参数以字节为单位,因此要复制 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

回答by Indy9000

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.

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

回答by Andy J Buchanan

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.

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

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.

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

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

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