50 votes

memcpy avec startIndex ?

Je souhaite copier un contenu d'une longueur spécifique d'une mémoire tampon à une autre à partir d'un point de départ spécifique. J'ai vérifié memcpy() mais il ne prend en compte que la longueur du contenu à copier alors que je souhaite également spécifier l'index de départ.

Existe-t-il une fonction qui permette de faire cela ou une bonne approche pour le faire avec le système existant ? memcpy fonction ?

1voto

Matthew Points 11

Ce site a besoin d'un moyen pour permettre des suivis anonymes en plus des réponses anonymes.

Pourquoi, plus d'une fois, ai-je vu cette affirmation insensée selon laquelle un "index" doit être exprimé en unités d'un octet ? C'est tout le contraire de la convention. Un "index" est généralement symbolique, une mesure dont le décalage physique en octets est déterminé par la taille de l'élément dans le tableau (ou le vecteur, qui peut même ne pas avoir la disposition physique d'un tableau, mais alors memcpy() n'est pas pertinent non plus bien sûr).

Ainsi, le 5e élément d'un tableau a pour "indice" 5, mais.. :

  • Si le tableau est de type char, le décalage d'octet de cet "index" est de 5.
  • Si le tableau est de type court (sur x86), le décalage d'octet de cet "index" est de 10.
  • Si le tableau est de type int (sur x86), le décalage d'octet de cet "index" est de 20.
  • Si le tableau est du type d'un grand objet de 48 octets, le décalage d'octets de cet "index" est de 240.

La question de savoir quelle est la bonne façon d'accéder à cet élément spécifique est une question secondaire. L'important est que vous compreniez la différence, que vous choisissiez l'une d'entre elles et que vous fassiez en sorte que le code soit correct.


Sur le sens des mots, je préférerais lire :

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

Je trouve que l'idée qu'un void * complètement générique puisse avoir un "index" est trompeuse. (Pendant que nous y sommes, "dest" et "source" ou "in" et "out" seraient beaucoup moins ambigus que "s1" et "s2". Le code n'a pas besoin d'autant de commentaires lorsque vous choisissez des noms de variables explicites).

0voto

CsTamas Points 1586

Il suffit d'ajouter l'index à l'adresse du tampon et de le transmettre à memcpy() comme paramètre source, par exemple copie du 3ème élément de la mémoire tampon b

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

Prenez également en compte le type d'éléments dans le tampon, la longueur (3e) du paramètre de memcpy() est en octets, donc pour copier 4 ints vous devez mettre 4*sizeof(int) - ce qui sera probablement 16 (sur un système 32 bits). Mais le type n'a pas d'importance pour l'adresse de départ, en raison de l'arithmétique des pointeurs :

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

0voto

Kip9000 Points 4462

Vous pourriez avoir une fonction comme ci-dessous.

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

Il peut être utilisé comme suit :

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

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

Vous devez vous assurer que le tampon de destination dispose de suffisamment d'espace pour copier les éléments.

0voto

Andy J Buchanan Points 1467

Si vous utilisez c++, il est probablement préférable d'utiliser std::copy() au lieu de memcpy(). std::copy peut prendre des pointeurs aussi facilement que des itérateurs.

par exemple

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

Comme pour memcpy(), il est de votre responsabilité de vous assurer que les pointeurs sont valides.

NOTE. Si votre utilisation est critique en termes de performances, vous trouverez peut-être qu'un memcpy() tel que détaillé dans les autres réponses est plus rapide, mais probablement pas de beaucoup.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X