Discussione su memcpy [C]
Moderatore: Staff
Regole del forum
1) Rispettare le idee altrui.
2) Evitare le offese dirette.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.
La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
1) Rispettare le idee altrui.
2) Evitare le offese dirette.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.
La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
- Blizzard
- Master
- Messaggi: 1509
- Iscritto il: mar 2 gen 2007, 22:53
- Nome Cognome: Giovanni Santostefano
- Slackware: 12.2
- Kernel: 2.6.27.7-smp
- Desktop: Fluxbox
- Contatta:
Discussione su memcpy [C]
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
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
- nuitari
- Linux 3.x
- Messaggi: 777
- Iscritto il: dom 14 ott 2007, 12:51
- Slackware: 12.0
- Località: San Colombano al Lambro
- Contatta:
memcpy funziona così:
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.
Codice: Seleziona tutto
void *memcpy(void *dest, const void *src, size_t n);
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:
Codice: Seleziona tutto
int a[] = {1,2,3,4,5,6,7,8,9};
Codice: Seleziona tutto
memcpy(a+2,a,sizeof(int)*4);
{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.
Potresti partire dal fondo dell'array, con un ciclo for al contrario:
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.
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");
}
Ciao, rogx.
- Blizzard
- Master
- Messaggi: 1509
- Iscritto il: mar 2 gen 2007, 22:53
- Nome Cognome: Giovanni Santostefano
- Slackware: 12.2
- Kernel: 2.6.27.7-smp
- Desktop: Fluxbox
- Contatta:
ciao,
capisco la tua soluzione, tuttavia volevo necessariamente effettuare lo shift senza utilizzare cicli :P ma solo con memcpy
comunque è una simpatica soluzione...
grazie
Gio
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:Codice: Seleziona tutto
memcpy(&myarray[a]+3, &myarray[a], sizeof(int)*3);
Codice: Seleziona tutto
memcpy(a+3,a,sizeof(int)*3);
grazie
Gio
-
- Iper Master
- Messaggi: 3174
- Iscritto il: lun 3 set 2007, 21:20
- Nome Cognome: Mario Vanoni
- Slackware: 12.2
- Kernel: 3.0.4 statico
- Desktop: fluxbox/seamonkey
- Località: Cuasso al Monte (VA)
Discussione su memcpy [C]
http://news.softpedia.com/news/Microsof ... 1722.shtml
http://stackoverflow.com/questions/8765 ... ion/876579
Incompatibilita` programmata, non ANSI C e gcc non lo conosce.
http://stackoverflow.com/questions/8765 ... ion/876579
Incompatibilita` programmata, non ANSI C e gcc non lo conosce.
- Blizzard
- Master
- Messaggi: 1509
- Iscritto il: mar 2 gen 2007, 22:53
- Nome Cognome: Giovanni Santostefano
- Slackware: 12.2
- Kernel: 2.6.27.7-smp
- Desktop: Fluxbox
- Contatta:
Re: Discussione su memcpy [C]
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
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
-
- Iper Master
- Messaggi: 3174
- Iscritto il: lun 3 set 2007, 21:20
- Nome Cognome: Mario Vanoni
- Slackware: 12.2
- Kernel: 3.0.4 statico
- Desktop: fluxbox/seamonkey
- Località: Cuasso al Monte (VA)
Re: Discussione su memcpy [C]
Giovanni, e` un problema per chi programma nei due ambienti,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.
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.