6
votes

MEMCY Copier partiellement sur lui-même

est-ce ok?

char buf[] = { 0, 1, 2 };
memcpy(buf, buf + 1, 2);


6 commentaires

-1: Que se passe-t-il quand tu as essayé?


+1, parce que je suis en désaccord avec PMG -1. "Ce qui s'est passé quand tu l'as regardé dans la norme?", Peut-être, mais il y a un risque réel d'expérimenter ce genre de chose, que vous pourriez l'essayer et qu'il "fonctionne", avec résultat {1,2, 2} dans le tampon. Alors quelle utilisation est le conseil pour l'essayer? Sera-t-il toujours fonctionner la semaine prochaine, ou lorsque vous allumez l'optimisation ou sur les ordinateurs de votre client?


@Steve Jessop: Je suis d'accord. L'exemple de l'OP (probablement) fonctionnera (probablement) en fonction de la mise en œuvre de la plate-forme cible particulière de memcpy , mais cela ne fait pas une bonne idée!


Chose est: il dit "Je sais que je pourrais utiliser Memmove ()" et il demande toujours si memcpy () est ok. Comment sache-t-il qu'il pourrait utiliser Memmove et ne pas savoir pour ne pas utiliser MEMCY avec des objets qui se chevauchent?


@PMG: Je suppose que j'étais un peu incertain. J'étais en quelque sorte trouvé une réponse définitive pour qu'il s'agisse d'un comportement indéfini, mais n'avez évidemment pas laissé de telle chose en code. Je l'ai essayé hors de curiosité et cela a fonctionné pour mon compilateur dans ce cas particulier.


La bibliothèque GNU C a commuté la mise en œuvre de MEMCY environ plusieurs fois. Parfois, il est même différent pour i686 vs i386 vs x86_64.


4 Réponses :


13
votes

Les effets de memcpy ne sont pas définis lorsque le chevauchement de l'entrée et de la sortie. Vous devez utiliser MemMove .


0 commentaires

5
votes

pas d'accord. Vous doit strud> utiliser MemMove code> lorsque la source et la destination se chevauchent.

IT pourrait em> fonctionner avec memcpy code>, en fonction de La mise en œuvre de votre compilateur, mais ce n'est pas quelque chose que vous devriez compter sur! p>


Une implémentation naïve typique peut être une copie d'octets par octet (UINT8) comme ceci: p>

typedef unsigned char uint8;

void * memcpy ( void * destination, const void * source, size_t num )
{
    const uint8* pSrc = (const uint8*)source;
    const uint8* const pSrcEnd = pSrc + num;
    uint8* pDst = (uint8*)destination;

    while (pSrc != pSrcEnd)
        *(pDst++) = *(pSrc++);

    return destination;
}


0 commentaires

4
votes

Le comportement est indéfini si les régions de mémoire se chevauchent, ce n'est pas correct.


0 commentaires

1
votes

C'est un comportement indéfini, mais je l'ai utilisé comme, xxx

où le point final de la destination est inférieur au point de départ de la source. Vous devez toujours utiliser Memmove pour être sûr ...


1 commentaires

La bibliothèque GNU C a commuté la mise en œuvre de MEMCY environ plusieurs fois. Parfois, il est même différent pour i686 vs i386 vs x86_64.