Pagina 1 di 1
Discussione su memcpy [C]
Inviato: mar 1 gen 2008, 15:43
da Blizzard
ciao ragazzi,
volevo aprire questa discussione circa il funzionamento della funzione memcpy.
Stavo scrivendo un piccolo codice per shiftare un array, quando utilizzando la memcpy in una maniera simile
memcpy(a+n,a,3*sizeof(x));
mi sono ritrovato un comportamento simile
{1,2,3,4,5,6,7,8,9} =shift +3 posizioni=> {1,2,3,1,2,3,
1,2,3}
insomma... al posto degli ultimi 123 ci dovrebbero essere 4,5,6
Come funziona in pratica la memcpy? fa una copia diretta della memoria?
Sarebbe il solo sistema che spieghi perchè a partire dalla metà della zona di copia i dati siano replicati.
Comunque il codice... e come ho risolto (anche se non mi piace) è accessibile alla fine di questa pagina
http://hackingcoder.blogspot.com/2008/0 ... ifter.html
ciao
Gio
Inviato: mar 1 gen 2008, 16:58
da nuitari
memcpy funziona così:
Codice: Seleziona tutto
void *memcpy(void *dest, const void *src, size_t n);
copia n bytes dall'area di memoria *src all'area di memoria *dest.
Ora, non avendo il tuo codice originale è un po' difficile dire quale sia l'errore, ma a spanne credo tu ti sia sovrascritto i dati da solo, dato che non copiavi i dati in un buffer temporaneo.
Es.:
Supponiamo di avere un array tipo:
facendo un
tu ti aspetteresti di avere:
{1,2,1,2,3,4,7,8,9}
ed invece ottieni
{1,2,1,2,1,2,7,8,9}
perchè? cosa succede? Succede che memcpy fa un ciclo, e comincia a copiare gli elementi.
Innanzitutto copia a[0] in a[2], per cui avremo:
{1,2,1,4,5,6,7,8,9}
quindi copia a[1] in a[3]
{1,2,1,2,5,6,7,8,9}
quindi copia a[2] in a[4], e qui il dato è stato già sovrascritto, per cui ottieni
{1,2,1,2,1,6,7,8,9}
ed infine, a[3] in a[5]
{1,2,1,2,1,2,7,8,9}
Ed ecco il risultato. Tutto questo lo risolvi passando i dati in un buffer temporaneo.
Inviato: mar 1 gen 2008, 17:06
da Blizzard
ciao,
avevo intuito un simile comportamento... infatti era l'unico modo per spiegarmi la ripetizione dei dati.
Infatti poi ho dovuto necessariamente allocare memoria di appoggio.
Grazie!
ciao
Gio
Inviato: mer 2 gen 2008, 10:57
da rogx
Potresti partire dal fondo dell'array, con un ciclo for al contrario:
Codice: Seleziona tutto
#include <stdio.h>
#include <string.h>
void main(void)
{
int myarray[12];
int a=0;
// carica l'array con 1, 2, 3, 4, ...
for (a=0;a<9;a++)
myarray[a]=a+1;
// lo scrive a video:
for (a=0;a<12;a++)
printf("%d ", myarray[a]);
printf("\n");
// esegue lo shift:
for (a=6;a>=0;a -= 3)
memcpy(&myarray[a]+3, &myarray[a], sizeof(int)*3);
// riscrive l'array a video:
for (a=0;a<12;a++)
printf("%d ", myarray[a]);
printf("\n");
}
nota che per non perdere gli ultimi valori l'array e' stato dichiarato piu' lungo di quanto e' il blocco di spostamento (3 nell'esempio)
Ciao, rogx.
Inviato: mer 2 gen 2008, 11:25
da Blizzard
ciao,
capisco la tua soluzione, tuttavia volevo necessariamente effettuare lo shift senza utilizzare cicli :P ma solo con memcpy
Questa comunque per l'aritmetica dei puntatori se non sbaglio puoi scriverla come:
comunque è una simpatica soluzione...
grazie
Gio
Discussione su memcpy [C]
Inviato: mer 20 mag 2009, 11:09
da Mario Vanoni
Re: Discussione su memcpy [C]
Inviato: mer 20 mag 2009, 12:24
da Blizzard
come al solito Microsoft tenta di costruirsi il suo piccolo "non standard" mondo.
Comunque che la memcpy possa generare buffer overflows sotto opportune disattenzioni non è una novità, specialmente sul lato Microsoft dell'informatica.
Se si troverà una soluzione migliore, soprattutto rispetto alle centinaia di migliaia di software scritte con la memcpy, allora sarà il comitato per lo standard a farcele conoscere.
ciao
Gio
Re: Discussione su memcpy [C]
Inviato: mer 20 mag 2009, 13:46
da Mario Vanoni
Blizzard ha scritto:come al solito Microsoft tenta di costruirsi il suo piccolo "non standard" mondo.
Comunque che la memcpy possa generare buffer overflows sotto opportune disattenzioni non è una novità, specialmente sul lato Microsoft dell'informatica.
Se si troverà una soluzione migliore, soprattutto rispetto alle centinaia di migliaia di software scritte con la memcpy, allora sarà il comitato per lo standard a farcele conoscere.
Giovanni, e` un problema per chi programma nei due ambienti,
M$ rifiuta memcpy, ANSI C e gcc non conoscono memcpy_s,
quindi il poveraccio dovra` mantenere due codici sorgente!
M$ con questo costruisce un "muro di Berlino" per tenersi lontano UNIX/Linux.
Vista la solerzia di ANSI, C89, C99, vecchio in confronto a gcc, icc od ai cc UNIX.