codice:
#include <iostream>
#include <cstring>
#include <cstdlib>
int main()
{
char stringa[250]="ci sono le mezze stagioni";
//L'area di memoria di origine e di destinazione si sovrappongono (stringa+4 ad esempio appartiene sia all'origine che alla destinazione) => memmove
memmove(stringa + 4, stringa, strlen(stringa)+1);
//L'area di memoria di origine e di destinazione non si sovrappongono => memcpy
memcpy(stringa, "non ", 4);
//L'area di memoria di origine e di destinazione si sovrappongono => memmove
memmove(stringa + 17, stringa + 12, strlen(stringa+12));
//L'area di memoria di origine e di destinazione non si sovrappongono => memcpy
memcpy(stringa+12, "piu' ",5);
std::cout<<stringa<<std::endl;
return 0;
}
Output:
codice:
matteo@teoubuntu:~/cpp/test$ g++ -O3 -Wall -Wextra -ansi -pedantic memmove.cpp -o memmove.x
matteo@teoubuntu:~/cpp/test$ ./memmove.x
non ci sono piu' le mezze stagioni
matteo@teoubuntu:~/cpp/test$
Se invece sostituisci tutte le memmove con memcpy, puoi ottenere risultati errati; sulla mia macchina, ad esempio:
codice:
matteo@teoubuntu:~/cpp/test$ g++ -O3 -Wall -Wextra -ansi -pedantic no_memmove.cpp -o no_memmove.x
matteo@teoubuntu:~/cpp/test$ ./no_memmove.x
non ci scio piu' leo llze stagioni
matteo@teoubuntu:~/cpp/test$
.
Questo accade perché la memcpy copia la memoria in maniera semplice, una cosa del tipo:
codice:
void * memcpy(void * destination, void * source, size_t num)
{
char * write=destination, * read=source;
while(num-- > 0)
*write++=*read++;
return destination;
}
per cui, se le aree di memoria si sovrappongono, è possibile che una parte del buffer di input venga sovrascritta prima di essere copiata. La memmove, invece, garantisce che la copia avvenga sempre come se il buffer di input venisse prima copiato in un buffer temporaneo. All'atto pratico poi nessuna memmove farà così, ma copierà in un verso piuttosto che nell'altro in base alla posizione reciproca delle due aree di memoria.