C++ 有startIndex的memcpy?

C++ 有startIndex的memcpy?,c++,memcpy,C++,Memcpy,我希望从一个特定的起点将特定长度的内容从一个缓冲区复制到另一个缓冲区。我选中了memcpy(),但它只需要复制内容的长度,同时我还想指定起始索引 有没有什么函数可以做到这一点,或者有什么好方法可以用现有的memcpy函数做到这一点?只需将偏移量添加到地址中即可。例如,如果要复制从第n个字节开始的缓冲区: memcpy( destination, source + N, sourceLen - N ); 这将复制到目标。如果还希望偏移目标-将偏移量添加到两个目标: memcpy( destina

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


有没有什么函数可以做到这一点,或者有什么好方法可以用现有的
memcpy
函数做到这一点?

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

memcpy( destination, source + N, sourceLen - N );
这将复制到
目标
。如果还希望偏移目标-将偏移量添加到两个目标:

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

只需将您想要的偏移量添加到缓冲区的地址

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

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

不需要索引,因为您只需按指定的字节数更新源指针即可。下面的包装器应该可以做到这一点

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

只需增加指向起始索引的指针

范例

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);
const unsigned char*src=reinterpret\u cast(您的源代码);
unsigned char*dest=reinterpret_cast(您的dest);
memcpy(dest,src+偏移量,len);

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

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

char a[10], b[20];
::memcpy(a,b+2,10);
还要考虑缓冲区中项目的类型,memcpy()的length(3rd)参数以字节为单位,因此要复制4个int,您应该放入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

我总是喜欢语法

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

您可以使用如下函数

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

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

如果使用C++,最好使用STD::Copy.(而不是MycPy.)。STD::复制可以像迭代器一样容易地使用指针。

e、 g

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


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

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

为什么我不止一次地看到“索引”必须以1字节为单位的疯狂断言?这与传统完全相反。“索引”通常是符号,其物理字节偏移量由数组中元素的大小决定(或者vector,它甚至可能没有数组的物理布局,但是memcpy()当然也不相关)

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

  • 如果数组是char类型,那么该“索引”的字节偏移量是5
  • 如果数组的类型为short(在x86上),则该“索引”的字节偏移量为10
  • 如果数组的类型为int(在x86上),则该“索引”的字节偏移量为20
  • 如果数组是某个大的48字节对象的类型,则该“索引”的字节偏移量为240
哪种方法是访问特定元素的正确方法是一个侧重点。重要的部分是您理解差异,选择一种方法,并使代码正确


关于词语的含义,我更愿意阅读:

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


我发现一个完全通用的void*可能有一个“索引”的想法是有误导性的。(在这里,“dest”和“source”或“in”和“out”比“s1”和“s2”模糊得多。在选择自解释变量名时,代码不需要那么多注释。)

这仅适用于源指向长度为1字节的类型的情况。对于所有其他情况,您将获得不正确的偏移量(void根本无法编译)@JaredPar:是的,那么需要更多的算术运算。这是一个稍微有点误导性的例子。它之所以有效,是因为char的长度保证为1字节。对于大小为1的所有其他类型,此代码将编译,但运行不正确(coures无效除外)。@JaredPar:IMHO Neil的答案完全正确。问题是“…我想指定起始索引”。向指针添加一个常量将考虑指向的类型的大小。例如,“int*p=…;p+=5;”将使“p”点大小为(int)*5字节。char在问题中根本没有提到,但是术语buffer稍微暗示了它。代码做我说的它做的,不管abuff的类型是什么。+1,做要求做的。它做你说的,我认为这是OP说的。但是这是否是OP想要的,可能有点争议。一个“起始索引”"提到了,但可以想象OP打算以字节为单位对索引进行量化,正如它与长度一样。如果它实际上不是源数组的索引,则需要使用更多类型转换。这可能是JaredPar假设的结果,从而得出数组类型影响请注意:MeMcPy是C,不是C++。虽然我经常使用它,但毫无疑问,MyCPy一般与主要的C++概念完全不同,比如类型安全、继承、异常等。很容易用MycPyp来把所有东西都拧起来。MycPy是C++标准的一部分,从C头的角度来看,它是如何提供的。曾经,C++本身提供了<代码> STD::复制< /COD>,它通常比<代码> MeMCPY好,加上更灵活,又有类型。你假设索引是字节索引,N是字节计数。在这种情况下,S1和S2也可能是类型化的char *@ Indeera,我唯一的假设是索引,就像大小字段n,以字节为单位指定。对于普通的旧对象,您的实现可以自由地使用memcpy实现std::copy。很高兴知道这一点。谢谢。+1Ditto。在任何时候复制内存时都不能太冗长
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 );
 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);