memcpy with startIndex?
我希望将特定长度的内容从一个缓冲区复制到特定起点。 我检查了
是否有任何函数可以做到这一点,或者有什么好的方法可以利用现有的
我总是喜欢语法
1 | memcpy( &dst[dstIdx], &src[srcIdx], numElementsToCopy * sizeof( Element ) ); |
只需将所需的偏移量添加到缓冲区的地址即可。
1 2 3 | char abuff[100], bbuff[100]; .... memcpy( bbuff, abuff + 5, 10 ); |
这会将从abuff [5]开始的10个字节复制到bbuff。
只需将偏移量添加到地址即可。例如,如果要复制从第N个字节开始的缓冲区:
1 | memcpy( destination, source + N, sourceLen - N ); |
这将复制到
1 | memcpy( destination + N, source + N, sourceLen - N ); |
不需要索引,因为您可以按指定的字节数简单地更新源指针。以下包装器可以解决问题
1 2 3 4 | void* memcpy_index(void *s1, const void *s2, size_t index, size_t n) { s2 = ((char*)s2)+index; return memcpy(s1, s2,n); } |
只需增加指向起始索引的指针即可。
例
1 2 3 | 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集合避免内存访问错误?
除了匿名答案之外,该网站还需要一种允许匿名后续活动的方法。
为什么我不止一次看到这种疯狂的断言,即"索引"必须以1字节为单位?这与惯例完全相反。"索引"通常是象征性的,它的物理字节偏移量由数组中元素的大小(或向量,它甚至可能没有数组的物理布局,但与memcpy()也无关)的度量来课程)。
因此,数组中的第5个元素具有"索引" 5,但是:
- 如果数组是char类型,则该"索引"的字节偏移为5。
- 如果数组的类型为short(在x86上),则该"索引"的字节偏移为10。
- 如果数组是int类型(在x86上),则该"索引"的字节偏移为20。
- 如果数组是某个48字节大对象的类型,则该"索引"的字节偏移为240。
哪种方法是访问该特定元素的正确方法是一个补充。重要的部分是您了解差异,选择其中一个,并使代码正确。
关于词语的含义,我宁愿阅读:
1 | void* memcpy_offset(void *s1, const void *s2, size_t offset, size_t n); |
比:
1 | void* memcpy_index(void *s1, const void *s2, size_t index, size_t n); |
我发现这样一个想法,即一个完全通用的void *可能会有一个"索引"来误导。 (虽然我们在这里,但"目标"和"源"或"输入"和"输出"的含义要比" s1"和" s2"少得多。选择不言自明的代码不需要太多注释。变量名称。)
如果您使用的是c ++,则最好使用std :: copy()而不是memcpy()。 std :: copy可以像迭代器一样轻松地获取指针。
例如
1 2 3 4 5 | 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()(如其他答案中所述),但可能不会很多。
您可能具有以下功能。
1 2 3 4 5 | 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)); } |
可以如下使用:
1 2 3 4 | int src[]={0,1,2,3,4,5,6}; int dst[15]; memcopy_index(dst,src,2,5); //copy 5 elements from index 2 |
您必须确保目标缓冲区有足够的空间来复制元素。
只需将索引添加到缓冲区的地址,并将其作为源参数传递给
1 2 | char a[10], b[20]; ::memcpy(a,b+2,10); |
还要考虑缓冲区中项目的类型,memcpy()的length(3rd)参数以字节为单位,因此要复制4个int,应放置4 * sizeof(int)-可能为16(在32位上)系统,但是类型与起始地址无关紧要,因为指针算法:
1 2 3 4 | 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 |