c++ - que - memcpy arduino
memcpy con startIndex? (9)
Deseo copiar contenido de una longitud específica de un búfer a otro desde un punto de inicio específico. memcpy()
pero solo se necesita copiar la longitud del contenido, mientras que también quiero especificar el índice de inicio.
¿Hay alguna función que pueda hacer esto o hay algún buen enfoque para hacerlo con la función de memcpy
existente?
Este sitio necesita una forma de permitir seguimientos anónimos además de respuestas anónimas.
¿Por qué, más de una vez, veo esta afirmación insana de que un "índice" debe estar en unidades de 1 byte? Es todo lo contrario de la convención. Un "índice" suele ser simbólico, una medida cuyo desplazamiento físico del byte está determinado por el tamaño del elemento en la matriz (o vector, que puede que ni siquiera tenga el diseño físico de una matriz, pero luego memcpy () es irrelevante para curso).
Por lo tanto, el quinto elemento de una matriz tiene "índice" 5, pero:
- Si la matriz es de tipo char, entonces el desplazamiento de bytes de ese "índice" es 5.
- Si la matriz es de tipo corto (en x86), entonces el desplazamiento de bytes de ese "índice" es 10.
- Si la matriz es de tipo int (en x86), entonces el desplazamiento de bytes de ese "índice" es 20.
- Si la matriz es del tipo de algún objeto grande de 48 bytes, entonces el desplazamiento de bytes de ese "índice" es 240.
La forma correcta de acceder a ese elemento específico es un punto lateral. Lo importante es que entienda la diferencia, elija una y haga que el código sea correcto.
Sobre el significado de las palabras, preferiría mucho leer:
void* memcpy_offset(void *s1, const void *s2, size_t offset, size_t n);
que:
void* memcpy_index(void *s1, const void *s2, size_t index, size_t n);
Creo que la idea de que un nulo * genérico podría tener un "índice" puede ser engañosa. (Mientras estemos aquí, "dest" y "source" o "in" and "out" serían mucho menos ambiguos que "s1" y "s2". El código no necesita tantos comentarios cuando selecciona autoexplicativos nombres de variables.)
No se requiere un índice porque simplemente puede actualizar el puntero de origen por el número especificado de bytes. La siguiente envoltura debería hacer el truco
void* memcpy_index(void *s1, const void *s2, size_t index, size_t n) {
s2 = ((char*)s2)+index;
return memcpy(s1, s2,n);
}
Si está utilizando c ++, probablemente sea mejor usar std :: copy () en lugar de memcpy (). std :: copy puede tomar punteros tan fácilmente como los iteradores.
p.ej
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 );
Al igual que con memcpy (), es su responsabilidad asegurarse de que los punteros sean válidos.
NOTA. Si su uso es crítico para el rendimiento, puede encontrar un memcpy () como se detalla en las otras respuestas más rápido, pero probablemente no mucho.
Siempre prefiero la sintaxis
memcpy( &dst[dstIdx], &src[srcIdx], numElementsToCopy * sizeof( Element ) );
Simplemente agregue el índice a la dirección del búfer y páselo a memcpy()
como parámetro de origen, por ejemplo, copie desde el tercer elemento del búfer b
char a[10], b[20];
::memcpy(a,b+2,10);
También tenga en cuenta el tipo de elementos en el búfer, la longitud (3er) parámetro de memcpy () está en bytes, por lo que para copiar 4 pulgadas debe poner 4 * sizeof (int) - que probablemente será 16 (en un 32 bit) sistema. Pero el tipo no importa para la dirección de inicio, debido a la aritmética de punteros:
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
Simplemente agregue el desplazamiento que desea a la dirección del búfer.
char abuff[100], bbuff[100];
....
memcpy( bbuff, abuff + 5, 10 );
Esto copia 10 bytes comenzando en abuff [5] a bbuff.
Simplemente aumenta tu puntero a tu índice de inicio.
Ejemplo
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);
¿Qué pasa con el uso de colecciones STL para evitar errores de acceso a la memoria?
Solo agrega el offset a las direcciones. Por ejemplo, si desea copiar el búfer a partir del byte Nth:
memcpy( destination, source + N, sourceLen - N );
Esto se copiará al destination
. Si también desea desplazar el destino, agregue el desplazamiento a ambos:
memcpy( destination + N, source + N, sourceLen - N );
Usted podría tener una función como la siguiente.
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));
}
Se puede utilizar como a continuación:
int src[]={0,1,2,3,4,5,6};
int dst[15];
memcopy_index(dst,src,2,5); //copy 5 elements from index 2
Debe asegurarse de que el búfer de destino tenga suficiente espacio para copiar los elementos.