Apropos de memcpy

Apropos de memcpy - C - Programmation

Marsh Posté le 12-02-2008 à 20:30:57    

Bonjour a tous,
je trouve nul part si cet effet de bord est encouragé ou pas par l'iso c99. Z'avez pas une idée par hasard ?
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. int main()
  4. {
  5.     int i;
  6.     int t[100];
  7.     t[0] = 0, t[1] = 1, t[2] = 2, t[3] = 3;
  8.     memcpy(t+4, t, 96*sizeof(int));
  9.     for(i=0; i < 30; i++)
  10.         printf("%d", t[i]);
  11.     printf("...\n" );
  12.     return 0;
  13. }

Reply

Marsh Posté le 12-02-2008 à 20:30:57   

Reply

Marsh Posté le 12-02-2008 à 20:35:58    

Quel effet de bord ?
 
Je ne vois rien d'anormal dans le comportement que tu constates...

Reply

Marsh Posté le 12-02-2008 à 20:46:08    

extrait du man de memcpy
 
DESCRIPTION
       The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas should not overlap.  Use memmove(3) if the memory areas do overlap.

Reply

Marsh Posté le 12-02-2008 à 21:06:31    

C'est très casse gueule ce que tu fais. J'imagine que de la sorte tu répètes la valeur des 4 premiers entiers sur tout le tableau. Si c'est vraiment ce que tu veux, utilises une fonction dédiée, car tu n'as aucune garantie que ça fonctionne ailleurs (bien que ça puisse ne ppas t'intéresser).
 
Toujours est-il que pour éviter des prises de tête assez sévères, utilise des comportements documentés, parce que le jour où ça va foirer, c'est le genre de code que tu ne soupçonneras pas et passera des heures (pour rester très gentil) à débugguer.
 
Edit: ha, ha, en voulant tester un peu ton code, je me suis rendu compte à quel point c'est tordu ton truc. En fait je supposais que la fonction memcpy() copiait les octets en commençant par les adresses basses. Ce qui fait que ton motif initial va se répéter sur le reste du tableau. Apparamment, ce n'est pas comme ça que ça fonctionne avec MinGW sous XP, qui se rapproche en fait plus de memmove. Bref, FUBAR.

Message cité 1 fois
Message édité par tpierron le 12-02-2008 à 21:16:51
Reply

Marsh Posté le 12-02-2008 à 21:36:19    

tpierron a écrit :

Edit: ha, ha, en voulant tester un peu ton code, je me suis rendu compte à quel point c'est tordu ton truc. En fait je supposais que la fonction memcpy() copiait les octets en commençant par les adresses basses. Ce qui fait que ton motif initial va se répéter sur le reste du tableau. Apparamment, ce n'est pas comme ça que ça fonctionne avec MinGW sous XP, qui se rapproche en fait plus de memmove. Bref, FUBAR.


 
Voila. [:romf]
Spour ça que je disais que je ne voyais rien d'anormal. [:klem3i1]

Reply

Marsh Posté le 13-02-2008 à 00:01:31    

Le but, c'est de faire de la répétition de pattern.
Sauf erreur de ma part et quelque soit l'environnement, memcpy() et memmove() n'ont aucune raison de partager la même implémentation.
memcpy() progresse par ordre croissant d'addresse, alors que memmove (il me semble) procede par la fin d'abord (pour feinter le chevauchement).
 
Moi aussi, ca me semblerait être une pratique autorisée... Le truc, c'est que l'implémentation de memcpy fais de la copie, non pas a coup d'octet, mais le plus souvent a coup de double. Ca et des histoires d'alignements pourraient eventuellement poser des problemes pour les motifs de petites tailles. Il me semble egalement que c'est un comportement documenté, en tous cas, j'ai déjà lu ça a plusieurs reprises.
Bref, est-ce que c'est bien de faire ca ? Est-ce que j'ai la garantie d'obtenir toujours le bon résultat, et cela, peu importe l'implementation de la librairie standard (Visiblement non, puisque ca n'a pas l'air de marcher avec mingw). Peut etre en étant moins gourmant, et en se restreignant a toutes les versions de gcc (donc la glibc), a t-on cette garantie ?
 
ps: pourquoi faire une fonction dédiée, si c'est le comportement naturel de memcpy.
 
Merci pour toutes vos réponses.

Reply

Marsh Posté le 13-02-2008 à 08:01:36    

Mais t'as lu les reponses avant de reposter? Y'a au moins deux fois la reponse a ta question!
Et si memmove se comporte comme tu dis (en commencant par la fin) alors il y a aussi un probleme si les deux zones memoire se chevauchent.

Reply

Marsh Posté le 13-02-2008 à 09:03:00    

Ton code est faux sur le principe, point. Rien ne garanti qu'il va marcher.

Reply

Marsh Posté le 13-02-2008 à 11:54:26    

memmove ça gère la superpostion mais que dans un sens.

Reply

Marsh Posté le 13-02-2008 à 14:09:35    

Heureusement que ca gère les deux sens
 

memmove ensures that the original source bytes in the overlapping region are copied before being overwritten.


 
http://msdn2.microsoft.com/en-us/l [...] r43e1f34d2


Message édité par Tarabiscote le 13-02-2008 à 14:10:22
Reply

Marsh Posté le 13-02-2008 à 14:09:35   

Reply

Marsh Posté le 13-02-2008 à 15:17:44    

tu as raison, je me suis mal exprimé, j'ai un mauvais souvenir de rotation de données où memmove ne marchait pas

Reply

Marsh Posté le 13-02-2008 à 18:53:38    

dave_tetehi a écrit :

Code :
  1. int t[100];
  2.     t[0] = 0, t[1] = 1, t[2] = 2, t[3] = 3;
  3.     memcpy(t+4, t, 96*sizeof(int));



Comportement indéterminé. Utiliser memmove() pour copier dans le même tableau..


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed